Why is there CopyOnWriteArrayList?


We know that ArrayList and LinkedList implement lists that are not thread-safe, so we have Vector, which is a thread-safe collection based on ArrayList, but both Vector methods add and get are synchronized. When a List is read or written by multiple threads, it must be queued, which is obviously inefficient. Is there a way to make the List read asynchronously and write synchronously? The answer is CopyOnWriteArrayList, which is read-write separate and has the advantage of improving the efficiency of thread access. Let’s compare the efficiency of CopyOnWriteArrayList and Vector.

import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CountDownLatch; /** * @Author: Jiaolian * @Date: Created in 2021-01-18 15:28 * @Description: Security List Public class SafelistTest {private static Vector<String safeList = new Vector<>(); private static Vector<String safeList = new Vector<>(); //private static CopyOnWriteArrayList<String> safeList = new CopyOnWriteArrayList<>(); private static CountDownLatch countDownLatch = new CountDownLatch(2); Throws InterruptedException {public static void main(String[] args) throws InterruptedException {public static void main(String[] args) throws InterruptedException { MySerive fishSerive = new MySerive(); long start = System.currentTimeMillis(); new Thread(()->{ fishSerive.read(); countDownLatch.countDown(); }," call read thread ").start(); new Thread(()->{ fishSerive.write(); countDownLatch.countDown(); }," call write thread ").start(); countDownLatch.await(); System. The out. Println (" cost: "+ (System. CurrentTimeMillis () - start)); } private static class mySerive {public void read() {for (int I =0; i<1000000; i++) { safeList.get(0); Public void write() {for (int I =0; i<100000; I++) {safelist.add (" call "); }}}}

When the safe collection uses Vector, the execution time is 100 milliseconds. When the safe collection uses CopyOnWriteArrayList, the execution time is 5000 milliseconds. Didn’t you say CopyOnWriteArrayList is more efficient? CopyOnWriteArrayList takes 50 times longer to execute than Vector! By looking at the source code, we found that when CopyOnWriteArrayList write elements is achieved by the way of backup array, when the multi-thread synchronization is intense, the amount of data will keep copying the array, a serious waste of memory. That’s why it took so long! But we still accept the idea of separating reading and writing!

What is weak consistency


import java.util.Iterator; import java.util.Vector; import java.util.concurrent.CopyOnWriteArrayList; /** * @Author: Jiaolian * @Date: Created in 2021-01-18 16:40 * @Description: CopyOnWriteArrayList is incongruant * @Created By: Practice * * public: call/public class WeekCopyOnWriteArrayListTest {private static CopyOnWriteArrayList < String > safeList = new CopyOnWriteArrayList<>(); //private static Vector<String> safeList = new Vector<>(); Public static void main(String[] args) throws InterruptedException {Safelist.add (" name "); SafeList. Add (" practice "); Iterator<String> iterator = safeList.iterator(); Thread, Thread, Thread, Thread, Thread, Thread, Thread, Thread, Thread, Thread, Thread, Thread. }); thread.start(); // The main thread waits for the thread to finish; thread.join(); while (iterator.hasNext()) { System.out.println(iterator.next()); }}}

As shown in the above code, the main thread waits for the completion of the execution of Thread child thread, and then loops to print the Safelist element. The final execution result is shown in the figure below

You may be wondering, didn’t Thread delete “call”? Shouldn’t the console just print “practice”? <String> Iterator = safelist.iterator (); <String> Iterator = safeList. The snapshot of the element is saved, so you can see the JVM memory state as shown in the figure below when the Thread thread finishes executing.

Fail – safe characteristics


The fail-fast is a fast collection detection mechanism that prevents incorrect collection operation. In general, if another thread modifies the collection while iterator iterates through the collection, let’s test, for example, the code above that tests for weak consistency. Private static CopyOnWriteArrayList

(); Private static Vector

(); What’s going to happen?

Pictured above, Java. Util. ConcurrentModificationException, concurrent modification error, but with CopyOnWriteArrayList execution is normal, the reason is CopyOnWriteArrayList delete data collection when the snapshot.

So it’s fail-safe and Vector is fail-fast!

conclusion


CopyOnWriteArrayList can be read/write separated, weak consistency, fail-safe, fail-safe, and so on. If you like, please pay attention to thumb up. My name is Lian [public number], while calling while practicing.