文档章节

ArrayList 初探

z2
 z2
发布于 2017/07/20 13:32
字数 615
阅读 2
收藏 0

一.初始化 底层是一个私有的未持久化的对象数组,无参构造函数情况下,jdk 1.6版本下,底层数组大小为10,jdk1.7版本数组大小为0;如果构造函数自定义容量大小或者参数为集合引用是,数组大小为自定义大小或者集合元素个数。

private transient Object[] elementData;

二. 自动扩容

private void ensureCapacityInternal(int minCapacity) {
    if (elementData == EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

如果elementData是null,则扩容取 DEFAULT_CAPACITY 和 minCapacity 中较大的值。如果它minCapacity 小于 DEFAULT_CAPACITY 这个方法会按 DEFAULT_CAPACITY 去扩容。

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}


private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

private static int hugeCapacity(int minCapacity) {
    if (minCapacity < 0) // overflow
        throw new OutOfMemoryError();
    return (minCapacity > MAX_ARRAY_SIZE) ?
        Integer.MAX_VALUE :
        MAX_ARRAY_SIZE;
}
  1. “>>1”,其实相当于除以2

  2. newCapacity 是 当前容量的 1.5 倍 newCapacity = oldCapacity + (oldCapacity >> 1)

  3. newCapacity 小于 minCapacity,则新容量 newCapacity = minCapacity

  4. newCapacity 超过数组的最大值 MAX_ARRAY_SIZE newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE

三.线程不安全

    //添加元素e    
    public boolean add(E e) {    
        // 确定ArrayList的容量大小    
        ensureCapacity(size + 1);  // Increments modCount!!    
        // 添加e到ArrayList中    
        elementData[size++] = e;    
        return true;    
    }    

赋值语句为:elementData[size++] = e,这条语句可拆分为两条:

  1. elementData[size] = e;
  2. size ++; 在单线程运行的情况下,如果 Size = 0,添加一个元素后,此元素在位置 0,而且 Size=1;
    而如果是在多线程情况下,比如有两个线程,线程 A 先将元素存放在位置 0。但是此时 CPU 调度线程A暂停,线程 B 得到运行的机会。线程B也向此 ArrayList 添加元素,因为此时 Size 仍然等于 0 (注意哦,我们假设的是添加一个元素是要两个步骤哦,而线程A仅仅完成了步骤1),所以线程B也将元素存放在位置0。然后线程A和线程B都继续运行,都增加 Size 的值。
    那好,现在我们来看看 ArrayList 的情况,元素实际上只有一个,存放在位置 0,而 Size 却等于 2。这就是“线程不安全”了

四.线程安全解决办法

1、继承Arraylist,然后重写或按需求编写自己的方法,这些方法要写成synchronized,在这些synchronized的方法中调用ArrayList的方法。

2、List list = Collections.synchronizedList(new ArrayList()); 效率低下

© 著作权归作者所有

共有 人打赏支持
z2

z2

粉丝 1
博文 12
码字总数 5379
作品 0
成都
ArrayList 底层数组扩容原理

原文出处:清浅池塘 ArrayList部分一共五篇文章了,并且引入了时间复杂度来分析,强烈建议大家一定要按顺序阅读,本文是第2篇,相关文章分别是: 1、ArrayList初始化 – Java那些事儿专栏 再...

清浅池塘
2017/12/02
0
0
集合框架2-ArrayList源码初探

由于笔者能力有限,本文也是学习的过程。部分内容可能会跳过,也希望大家可以不吝指导!~ 源码版本JDK1.8  数组是最常用的数据结构,相信大家对数组以及由数组实现的ArrayList的使用已经非常...

偏偏注定要落脚丶
2017/11/08
0
0
Jquery File upload 初探

官网:https://blueimp.github.io/jQuery-File-Upload/ 可以看到官方提供了几种不同的方案:我用的是basic plus ui 的样式 源码直接从github上下载即可: 要用到自己的项目里面,还是要注意几...

LonnyDong
2016/04/15
147
0
涨姿势:深入 foreach循环

foreach 循环 初探 我们知道集合中的遍历都是通过迭代(iterator)完成的。 也许有人说,不一定非要使用迭代,如: 这种方式对于基于链表实现的List来说,是比较耗性能的。 因为get(int i)方...

一只阿木木
06/13
0
0
WinForms UI控件初探:Grid Control 、Data Grid、TreeList

Grid Control 、Data Grid、Spreadsheet、Data Editor、TreeList: 超乎你想象!WinForms Grid Control处理100万行数据到底有多快? WinForms界面控件初探:处理速度飞快的WinForms Data Gri...

百mumu
2016/07/13
17
0

没有更多内容

加载失败,请刷新页面

加载更多

主流的消息队列MQ比较,详解MQ的4类应用场景

目前主流的MQ 1.ZeroMQ 号称最快的消息队列系统,尤其针对大吞吐量的需求场景。 扩展性好,开发比较灵活,采用C语言实现,实际上只是一个socket库的重新封装,如果做为消息队列使用,需要开发...

游人未归
42分钟前
2
0
React 服务器渲染原理解析与实践

网盘下载地址 React 服务器渲染原理解析与实践 本套课程,讲解了React中SSR技术的整个搭建思路及流程,完整的从原理上讲清楚了SSR的概念,重点在于讲解编写SSR框架遇到的各种知识点,以及细节...

qq__2304636824
今天
2
0
Jenkins使用

clean install -Dmaven.test.skip=true

1713716445
今天
1
0
多线程

1. 多线程概念。并发和并行的概念。 多线程指的是一段时间内cpu同时执行多个线程。一个程序至少运行>=1个进程,进程就是运行中的程序,而一个进程至少运行>=1个线程,线程是操作系统能调度的...

鱼想吃肉
今天
3
0
HBase 表修复在线方式和离线方式

一、在线修复 1.1 使用检查命令 $ ./bin/hbase hbck 该命令可完整修复 HBase 元数据信息;存在有错误信息会进行输出; 也可以通过如下命令查看详细信息: $ ./bin/hbase hbck -details 1.2 ...

Ryan-瑞恩
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部