标签:iterator his 操作 ring arraylist zed tor val exp
底层:Object数组,非线程安全
默认容量:10,其实是0,第一次add时,才会主动去扩容
每一扩容,变为原来容量的1.5倍。10->15->22
/*      */   private void grow(int minCapacity)
/*      */   {
/*  254 */     int oldCapacity = elementData.length;
/*  255 */     int newCapacity = oldCapacity + (oldCapacity >> 1);
/*  256 */     if (newCapacity - minCapacity < 0)
/*  257 */       newCapacity = minCapacity;
/*  258 */     if (newCapacity - 2147483639 > 0) {
/*  259 */       newCapacity = hugeCapacity(minCapacity);
/*      */     }
/*  261 */     elementData = Arrays.copyOf(elementData, newCapacity);
/*      */   }
非线程安全的case:ConcurrentModificationException
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            });
            thread.start();
        }
    }
为什么会报错:遍历ArrayList时,另一线程执行add操作,会造成modCount变化,fail-fast思想
 */     final void checkForComodification() {
/*  900 */       if (modCount != expectedModCount) {
/*  901 */         throw new ConcurrentModificationException();
/*      */       }
/*      */     }
Exception in thread "Thread-25" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at java.util.AbstractCollection.toString(AbstractCollection.java:461)
	at java.lang.String.valueOf(String.java:2994)
	at java.io.PrintStream.println(PrintStream.java:821)
	at com.hashmapt.ArrayListTest.lambda$0(ArrayListTest.java:29)
	at java.lang.Thread.run(Thread.java:745)
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f, c4894981-260b-4b7b-8076-168703f7e8ba]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f, c4894981-260b-4b7b-8076-168703f7e8ba, c201001b-41a8-4919-ad5f-5e36bd86a56b]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f, c4894981-260b-4b7b-8076-168703f7e8ba, c201001b-41a8-4919-ad5f-5e36bd86a56b, a492afac-264b-4111-9876-3e0e01b606db, 48dcca36-b425-451e-ab8b-1ad0967bfa91]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f, c4894981-260b-4b7b-8076-168703f7e8ba, c201001b-41a8-4919-ad5f-5e36bd86a56b, a492afac-264b-4111-9876-3e0e01b606db, 48dcca36-b425-451e-ab8b-1ad0967bfa91, 65c3cb2c-b4d4-4b59-ad2a-0c2194733d58]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 96f5bb81-c50b-441b-9833-e81c364b3c5f, c4894981-260b-4b7b-8076-168703f7e8ba, c201001b-41a8-4919-ad5f-5e36bd86a56b, a492afac-264b-4111-9876-3e0e01b606db, 48dcca36-b425-451e-ab8b-1ad0967bfa91, 65c3cb2c-b4d4-4b59-ad2a-0c2194733d58, 80dca1e1-c3bb-4b70-9cbd-f3ebfb699093]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7]
[82b9f5c7-7c17-48a1-87e0-e1ff90e084bb, fd427bbf-6adf-45af-b806-5af9a044d6d7, 9
    public static void main(String[] args) {
//        List<String> list = new ArrayList<String>();
        List<String> list = new Vector<String>();
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            });
            thread.start();
        }
    }
Vector是线程安全的容器,原理是对add,remove,iterator等所有方法都加synchronized锁
/*      */   public synchronized boolean add(E e)
/*      */   {
/*  781 */     modCount += 1;
/*  782 */     ensureCapacityHelper(elementCount + 1);
/*  783 */     elementData[(elementCount++)] = e;
/*  784 */     return true;
/*      */   }
此容器虽然线程安全,但是效率极低,使用场景很少
    public static void main(String[] args) {
//        List<String> list = new ArrayList<String>();
//        List<String> list = new Vector<String>();
        List<String> list = Collections.synchronizedList(new ArrayList<>());
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            });
            thread.start();
        }
    }
其原理同Vector,对所有操作加synchronized锁
    public static void main(String[] args) {
//        List<String> list = new ArrayList<String>();
//        List<String> list = new Vector<String>();
//        List<String> list = Collections.synchronizedList(new ArrayList<>());
        List<String> list = new CopyOnWriteArrayList<String>();
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(() -> {
                list.add(UUID.randomUUID().toString());
                System.out.println(list);
            });
            thread.start();
        }
    }
原理:写时复制,即只对add操作加锁,读操作不加锁。
add时,拷贝一份副本到内存,扩容后,将array指针指向新的数组
/*      */   public boolean add(E e)
/*      */   {
/*  434 */     ReentrantLock lock = this.lock;
/*  435 */     lock.lock();
/*      */     try {
/*  437 */       Object[] elements = getArray();
/*  438 */       int len = elements.length;
/*  439 */       Object[] newElements = Arrays.copyOf(elements, len + 1);
/*  440 */       newElements[len] = e;
/*  441 */       setArray(newElements);
/*  442 */       return true;
/*      */     } finally {
/*  444 */       lock.unlock();
/*      */     }
/*      */   }
此博客详细介绍了CopyOnWrite的使用场景及优缺点
JDK1.8 CopyOnWriteArrayList源码学习
标签:iterator his 操作 ring arraylist zed tor val exp
原文地址:https://www.cnblogs.com/lt123/p/13289146.html