`
wsmajunfeng
  • 浏览: 492103 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

ArrayList线程不安全分析

 
阅读更多

一个 ArrayList ,在添加一个元素的时候,它可能会有两步来完成:
1. 在 Items[Size] 的位置存放此元素;
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。这就是“线程不安全”了。
线程不安全的例子:

public class ArrayListInThread implements Runnable {
    List<String> list1 = new ArrayList<String>(1);// not thread safe

//    List<String> list1 = Collections.synchronizedList(new ArrayList<String>());// thread safe
    public void run() {
        try {
            Thread.sleep((int)(Math.random() * 2));
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        list1.add(Thread.currentThread().getName());
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadGroup group = new ThreadGroup("testgroup");
        ArrayListInThread t = new ArrayListInThread();
        for (int i = 0; i < 10000; i++) {
            Thread th = new Thread(group, t, String.valueOf(i));
            th.start();
        }
      
        while (group.activeCount() > 0) {
            Thread.sleep(10);
        }
        System.out.println();
        System.out.println(t.list1.size()); // it should be 10000 if thread safe collection is used.
    }
}

分享到:
评论
1 楼 zy116494718 2012-10-17  
你这个例子和你上面解释的有冲突吧,按你上面解释的,那么list1的个数并不会减少,还应该是10000个,而只是里面的值可能多了几个null值,因为两个线程在同一个存放位置赋了两遍值,然后又都把size加1了。至于为什么list1.size会少于10000,我也不得其解,正在研究中。

相关推荐

    (Java源码阅读) ArrayList为什么线程不安全?

    使用Collections.sychronizedList方法是线程安全的。 查看JDK文档,在结构上修改ArraysList的方法有 分析源码发现,在add方法中的elementData[size++] = e;存在线程不安全的风险。 elementData与size都是全局变量...

    java ArrayList的使用与分析

    java的 ArrayList的使用与分析

    ArrayList源码和多线程安全问题分析

    主要介绍了ArrayList源码和多线程安全问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面小编和大家一起来学习一下吧

    基于jdk1.8 的ArrayList的源码分析

    前言:一说到ArrayList的大家可能立马想到的就是:有序、可重复、查找快但是增删慢、线程不安全。但是具体的原因都不是很清楚,本文就会根据这些问题和大家一起去学习。主要会从ArrayList的构造方法、增加元素、删除...

    深入线程安全容器的实现方法

    在C#早期版本中已经实现了线程安全的ArrayList,可以通过下面的方式构造线程安全的数组列表:var array = ArrayList.Synchronized(new ArrayList()); 我们从Synchronized方法入手,分析它的源代码看是

    ArrayList源码分析.docx 等

    来自视频课笔记 面试肯定没问题 包含线程安全的list和不安全的list

    Java进阶课程系列之ArrayList集合底层源码实战分析

    其他方面,ArrayList 是非线程安全类,并发环境下,多个线程同时操作 ArrayList,会引发不可预知的错误。?本节课程会带着大家去学习集合底层源码是什么个结构,他在做什么事情,能做到什么事情,会出现的问题以及...

    java Vector和ArrayList的分析及比较

    主要介绍了java Vector和ArrayList的分析及比较的相关资料,Vector是多线程安全的,而ArrayList不是,本文主要做对比对这两个方法,需要的朋友可以参考下

    ArrayList 源码深度解析

    ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object...size 表示当前数组的大小,int类型,未使用volatile修饰,非线程安全; modCou

    javalist数据结构-Java数据结构-------List.pdf

    区别是ArrayList不是线程安全的,Vector绝⼤多数⽅法做了线程同步。 LinkedList通过双向链表实现。 源代码分析 1、添加元素到列表尾端(Appends the specified element to the end of this list.) ArrayList:当所需...

    java并发包&线程池原理分析&锁的深度化

    注意: Vector线程安全、ArrayList 并发队列 在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队 列,一个是以BlockingQueue接口为代表的阻塞队列,无论哪种都继承自Queue。

    java8源码-csn-list:ArrayList、LinkedList、Vector、Stack源码分析

    不是线程安全的。ArrayList包含了两个重要的对象:elementData(Object[]类型的数组) 和 size 遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高 转数组:Integer[] newText = v.toArray(new Integer[v....

    你知道synchronizedList和Vector底层原理实现和区别吗?其实开始我也不知道!(超详细源码分析)

    因为Vector和ArrayList除了数组扩容有点差别,还有加锁使Vector迈进了线程安全的行列外,底层实现大约是没有太大区别的!基本一致!线程安全问题更是另当别论了!继续往下看就OK! 扩容的区别: 从内部实现机制来讲...

    超级有影响力霸气的Java面试题大全文档

    ArrayList 和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector...

    java面试笔试资料包括JAVA基础核心知识点深度学习Spring面试题等资料合集.zip

    第五题 如何保证集合是线程安全的.pdf 第八题 Java并发类库提供的线程池有哪几种 分别有什么特点.pdf 第六题 synchronized和ReentLock有什么区别.pdf 第四题 ArrayList LinkedList Vector的区别.pdf docker讲得最...

    java类的设计举例-animal

    一.Animal类的设计要求: 根据实际需求设计Animal类,并完成以下功能: 1. 输出全部信息 2. 对2个实例进行比较 3. 使用static对共同的属性进行修饰 ...8. 利用ArrayList集合收集动物的年龄信息,并对其进行分析。

    基于javatcpsocket通信的拆包和装包源码-all-in-one:知识点总结

    基于java tcp socket通信的拆包和装包源码 基础 集合 List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问,查找元素效率...1、Vector是线程同步的,所以它也是线程安全的,而ArrayLi

    java8集合源码分析-LearningNotes:Java笔记

    组件、JMM、线程安全、锁优化 磁盘操作、字节操作、字符操作、对象操作、网络操作、NIO 运行时数据区域、垃圾收集、内存分配机制、类加载机制、性能调优监控工具 Java 常见的 10 余种设计模式,全 23 种设计模式逐步...

    java 面试题 总结

    ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector...

Global site tag (gtag.js) - Google Analytics