zoukankan      html  css  js  c++  java
  • ArrayList 线程安全

      都说ArrayList是线程不安全的,那为什么不安全呢。根据官方提供的源码,

    我是这样理解的,ArrayList的成员方法都不是原子操作的,比如add(E)方法,该方法是在集合的尾部加入一个一个元素.

    add(E)源码如下:

      /**
         * Appends the specified element to the end of this list.
         *
         * @param e element to be appended to this list
         * @return <tt>true</tt> (as specified by {@link Collection#add})
         */
        public boolean add(E e) {
            ensureCapacityInternal(size + 1);  // Increments modCount!!
            elementData[size++] = e;
            return true;
        }
    

       网上的思路大致是这样的:

    add(E)操作有两步,1>尾部添加元素 2>修改集合的容量 ,容量加一。

    因为是两步,所以必然存在A走完了第一步骤,比如将"张三"放在了index=10的地方,此时还没来得及修改容量,

    此时A被挂起,线程B切进来了,因为总容量没变,所以继续在尾部添加,于是index=10的位置被B线程的值占用了,

    也就是A添加的值操作就被B冲了,后面的操作继续,A修改容量加1,B修改容量加1。此时容量增加了2,元素只加入了1,所以线程不安全

      这样理解没问题,只是根据源码,先执行的是修改容量,然后才是添加元素。这该怎么解释啊?

    先修改了容量,哪怕A被暂停了,B执行了,那么结果也是容量增加了2,哪怕后续的操作发生异常,那也没问题啊,因为ArrayList是容许空值得啊!!

    求解啊,各位大神

    继续研究,更让人痛苦,下面是测试代码:

    package sourceCode.ArrayList;
    
    import java.util.ArrayList;
    
    public class arrayListTest implements Runnable {
    
    	private ArrayList<Integer> arry = null;
    
    	public arrayListTest(ArrayList<Integer> arry) {
    		this.arry = arry;
    	}
    
    	@Override
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			arry.add(1);
    		}
    		System.out.println(arry.size());
    
    	}
    
    	public static void main(String[] args) {
    		ArrayList<Integer> a = new ArrayList<Integer>();
    		for (int i = 0; i < 100; i++) {
    			new Thread(new arrayListTest(a)).start();
    		}
    	}
    }
    

     解读:这例子也不是我写的。很好理解,100个线程,每个线程向集合中添加10个元素,按理最终集合容量应该是1000,但是运行结果不是的,

         所以说,的确是线程不安全的,但是我理解不透啊!!!

     

    求指点,路过的各路大神

  • 相关阅读:
    ##JDBC
    《人月神话》阅读笔记(三)
    《人月神话》阅读笔记(二)
    《人月神话》阅读笔记(一)
    记账小软件开发(网页版)(四)
    记账小软件开发(网页版)(三)
    记账小软件开发(网页版)(二)
    记账小软件开发(网页版)(一)
    课程信息管理系统
    Java课程作业之动手动脑(六)
  • 原文地址:https://www.cnblogs.com/yesiamhere/p/6606523.html
Copyright © 2011-2022 走看看