`
wsmajunfeng
  • 浏览: 498178 次
  • 性别: 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,我也不得其解,正在研究中。

相关推荐

    ArrayList的线程安全测试

    然而,ArrayList本身并不是线程安全的,这意味着在多线程环境中,多个线程同时访问和修改ArrayList时,可能会出现数据不一致或者竞态条件等问题。本测试着重于分析ArrayList在并发环境下的行为,并探讨如何确保其...

    java ArrayList的使用与分析

    - ArrayList 默认不是线程安全的,多线程环境下使用时需要手动同步,或者使用 `Collections.synchronizedList(ArrayList list)` 创建线程安全的 ArrayList。 6. **性能考虑** - ArrayList 的插入和删除操作在中间...

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

    ArrayList源码和多线程安全问题分析 在 Java 编程语言中,ArrayList 是一个常用的集合类,它提供了动态数组的实现,能够存储大量的数据。但是,在多线程环境下,ArrayList 并不是线程安全的。这篇文章主要介绍了 ...

    ArrayList源码分析(含jdk1.8).pdf

    5. ArrayList不是线程安全的,但提供了fail-fast机制来维护集合的稳定性; 6. 在JDK1.8中,引入了一些改变以提高性能和效率,例如延迟初始化; 7. ArrayList的序列化需要特殊处理,以适应其内部数组的transient属性...

    线程安全Vector

    ##### 线程安全性分析 虽然 `Vector` 的方法都是同步的,但这并不意味着在所有情况下都可以无脑使用 `Vector` 而不用担心线程安全问题。例如,在多线程环境中,如果不恰当地使用 `Vector`,依然可能遇到线程安全问题...

    ArrayList数据结构的分析

    ArrayList本身不是线程安全的,这意味着在多线程环境下,如果不加同步控制,可能会出现数据不一致的问题。如果需要线程安全的列表,可以使用`CopyOnWriteArrayList`。 8. **性能对比与选择**: ArrayList与...

    ArrayList源码分析

    ArrayList不是线程安全的,这意味着在多线程环境下,对ArrayList的操作可能导致数据不一致。如果需要线程安全的列表,应使用`CopyOnWriteArrayList`。 7. **ArrayList与LinkedList的比较** - ArrayList更适合于...

    ArrayList类操作程序实例

    ArrayList不是线程安全的,这意味着在多线程环境下,对ArrayList的操作需要额外的同步措施,如使用`Collections.synchronizedList(ArrayList&lt;T&gt; list)`进行同步包装。 十、性能考量 1. 插入和删除元素:ArrayList在...

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

    本文将深入探讨线程安全容器的实现方法,以C#为例,分析ArrayList的线程安全实现,并讨论其他常见的线程安全容器。 首先,C#中的ArrayList.Synchronized方法是用来创建一个线程安全的ArrayList包装器。这个方法通过...

    ArrayList源码分析.docx 等

    ArrayList 不是线程安全的,这意味着在多线程环境下,多个线程同时操作 ArrayList 可能会导致数据不一致或者异常。例如,一个线程在添加元素的同时,另一个线程可能正在扩容数组,这可能会导致并发问题。为了解决这...

    Vector 与ArrayList区别

    - **ArrayList**:是非同步的,不提供内置的线程安全性。如果多个线程同时访问 `ArrayList`,则需要外部同步机制来确保线程安全。 **2. 数据增长策略** - **Vector**:默认情况下,当添加元素导致内部数组容量...

    JAVA提高第十篇 ArrayList深入分析

    3. 可变性:ArrayList不是线程安全的,因此在多线程环境下使用时需要额外的同步措施,或者使用CopyOnWriteArrayList等线程安全的替代品。 4. 性能:由于ArrayList底层是数组,访问元素的时间复杂度是O(1),而插入或...

    ArrayList LinkedList Vector性能测试

    在Java编程语言中,ArrayList、...而Vector虽然提供了线程安全,但其性能通常低于ArrayList和LinkedList,更适合于多线程环境且对性能要求不那么敏感的应用。在实际开发中,选择哪种数据结构应根据具体需求来决定。

    线程安全在Java中的应用与实践.pptx.pptx

    - **非线程安全集合类**:如ArrayList、HashMap等,需要程序员自己添加同步机制来确保线程安全。 6. **线程安全问题的实战案例分析** - **竞态条件**:多个线程同时修改共享变量,导致结果不可预测。 - **死锁**...

    ArrayList的底层原理Java系列2021.pdf

    本文将深入分析ArrayList的底层原理,包括其数据结构、线程安全性问题以及实现方式。 一、ArrayList的数据结构 ArrayList内部是基于数组的数据结构进行设计的,这个数组可以存储任意类型的对象,因为它内部使用的...

    ArrayList源码.zip

    如果需要线程安全的列表,可以使用Collections的`synchronizedList`方法对ArrayList进行包装,或者选择线程安全的Vector类。 源码分析中,我们还可以看到ArrayList是如何实现迭代器(Iterator)的。迭代器是Java...

    有关于C#的程序(ArrayList类,动态添加,删除的)

    虽然ArrayList很方便,但它不是线程安全的,所以在多线程环境下需要额外的同步措施。此外,ArrayList的性能对于大型数据集可能不如更现代的集合类型,如List,后者提供了更强的类型安全性。 在提供的资源中,...

    JDK1.6中Arraylist,Vector,LinkedList源码

    3. 线程安全:分析Vector如何实现线程安全,以及这对其性能的影响。 4. 链表结构:研究LinkedList的Node类,理解链表节点的结构和操作方式。 5. 性能优化:查看源码中是否存在针对特定操作的优化,例如ArrayList的...

Global site tag (gtag.js) - Google Analytics