Why 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. Vector, however, both add and get methods are qualified with synchronized. When multiple threads have to queue to read and write a List, it’s obviously inefficient. Is there a way to increase efficiency by making the thread asynchronous when reading a List and synchronous when writing a List? The answer is CopyOnWriteArrayList, which is read/write separated. The benefit is to improve thread access efficiency. Let’s compare CopyOnWriteArrayList with Vector execution efficiency.

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: Created in 2021-01-18 15:28 Public class SafeListTest {private static Vector<String> safeList = new Vector<>(); //private static CopyOnWriteArrayList<String> safeList = new CopyOnWriteArrayList<>(); private static CountDownLatch countDownLatch = new CountDownLatch(2); Public static void main(String[] args) throws InterruptedException {// Initialize safelist.add (" call "); MySerive fishSerive = new MySerive(); long start = System.currentTimeMillis(); new Thread(()->{ fishSerive.read(); countDownLatch.countDown(); }," call read thread ").start(); new Thread(()->{ fishSerive.write(); countDownLatch.countDown(); }," write thread ").start(); countDownLatch.await(); System. The out. Println (" cost: "+ (System. CurrentTimeMillis () - start)); } private static class MySerive {// read 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 "); }}}}Copy the code

When using a Vector, the execution time is 100ms. When using CopyOnWriteArrayList, the execution time is 5000 ms. Don’t you say CopyOnWriteArrayList is more efficient? But CopyOnWriteArrayList takes 50 times longer to execute than Vector! Through looking at the source code, we found that when CopyOnWriteArrayList writing elements is realized by the way of backup array, when multi-thread synchronization is fierce, the data will keep copying array, serious memory waste. That’s why it takes too long! But we still endorse the idea of read-write separation!

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 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 (" call "); SafeList. Add (" practice "); Iterator<String> iterator = safeList.iterator(); Thread Thread = new Thread(()->{safelist.remove (0); }); thread.start(); // The main thread waits for the thread to complete; thread.join(); while (iterator.hasNext()) { System.out.println(iterator.next()); }}}Copy the code

The main thread waits for the thread child thread to finish executing, and then prints the safeList element in a loop. The final execution result is shown in the figure below

You may be wondering if thread has been removed “called”. Shouldn’t the console just print the word “practice”? Iterator = safelist.iterator (); Iterator = safelist.iterator (); Iterator = safelist.iterator (); A snapshot of the elements is saved, so you can see the JVM memory state as shown below after the thread completes execution!

Fail – safe characteristics

Fail-safe is a fast fail-safe system for collection detection **** to prevent collection from operating incorrectly. ** In general, if a thread iterates through a collection and another thread changes the collection, we can test the code for weak consistency as described above. Private static CopyOnWriteArrayList safeList = new CopyOnWriteArrayList<>(); Private static Vector safeList = new 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 he is fail-safe and Vector is fail-fast!

conclusion

To summarize, we used code briefs to explain the concepts of CopyOnWriteArrayList: read-write separation, weak consistency, fail-safe, fail-safe, and how to implement it. If you like it, please like it and follow it. My name is Lian [public number], while calling while practicing.