文档章节

ArrayList 初探

z2
 z2
发布于 2017/07/20 13:32
字数 615
阅读 2
收藏 0
点赞 0
评论 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
博文 8
码字总数 4708
作品 0
成都
ArrayList 底层数组扩容原理

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

清浅池塘 ⋅ 2017/12/02 ⋅ 0

集合框架2-ArrayList源码初探

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

偏偏注定要落脚丶 ⋅ 2017/11/08 ⋅ 0

Jquery File upload 初探

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

LonnyDong ⋅ 2016/04/15 ⋅ 0

JAVA 持有对象——容器初探

引言 如果一个程序只包含固定数量的且其生命周期都是已知对象,那么这是一个非常简单的程序——《think in java》 了解容器前,先提出一个问题,ArrayList和LinkedList谁的处理速度更快呢? ...

jiangmitiao ⋅ 2015/08/01 ⋅ 2

涨姿势:深入 foreach循环

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

一只阿木木 ⋅ 06/13 ⋅ 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 ⋅ 0

XStream 初探,很给力

主要代码 (maven)所续的pom文件: 注意事项:如果想在java 项目中运行这个需要添加一些关联的包不然的话会报一个:

史上最强的弟子 ⋅ 2016/11/10 ⋅ 0

XStream 初探,很给力

主要代码/** Xstream 测试 @return TestVo类代码:public class TestVo {private List list; public List getList() {return list;} public void setList(List list) {this.list = list;} @O......

史上最强的弟子 ⋅ 2016/11/10 ⋅ 0

XStream 初探,很给力

主要代码/** Xstream 测试 @return TestVo类代码:public class TestVo {private List list; public List getList() {return list;} public void setList(List list) {this.list = list;} @O......

史上最强的弟子 ⋅ 2016/11/10 ⋅ 0

XStream 初探,很给力

主要代码/** Xstream 测试 @return TestVo类代码:public class TestVo {private List list; public List getList() {return list;} public void setList(List list) {this.list = list;} @O......

史上最强的弟子 ⋅ 2016/11/10 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周日乱弹 —— 这么好的姑娘都不要了啊

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @TigaPile :分享曾惜的单曲《讲真的》 《讲真的》- 曾惜 手机党少年们想听歌,请使劲儿戳(这里) @首席搬砖工程师 :怎样约女孩子出来吃饭,...

小小编辑 ⋅ 15分钟前 ⋅ 1

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部