Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize the CopyOnWrite of Java

2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the Java CopyOnWrite how to achieve the relevant knowledge, the content is detailed and easy to understand, the operation is simple and fast, with a certain reference value, I believe you will have something to gain after reading this Java CopyOnWrite article, let's take a look at it.

Concept

What is CopyOnWrite? literally, it is copied at the time of writing. It seems very simple, so how do you copy when you write?

Let's talk about the thought first, how to realize it, and analyze it later.

CopyOnWrite's idea is: when adding elements to a container, it is not added directly in the current container, but copied out of a new container, adding elements in the new container, and then pointing the reference of the original container to the new container, thus realizing write-in copy.

Do you remember that when you mention a database, you usually say master-slave replication, read-write separation? Is the design idea of CopyOnWrite like the separation of master-slave replication, reading and writing, as often said?

Advantages and disadvantages

After understanding the concept, it should be easier to understand its advantages and disadvantages.

The advantage is that reading and writing can be performed in parallel, because reading is the original container and writing is a new container, so they do not affect each other, so reading and writing can be executed in parallel. In some high concurrency scenarios, the response time of the program can be improved.

However, as you can see, CopyOnWrite copied a new container when it was written, so we have to consider its memory overhead and return to an idea that has been emphasized when learning algorithms: trade space for time.

It is important to note that it only guarantees the ultimate consistency of the data. Because when reading, the content read is the content of the original container, and the newly added content cannot be read.

Based on its advantages and disadvantages, it should be concluded that CopyOnWrite is suitable for scenarios with very few writes, and can tolerate temporary inconsistencies between reading and writing. if your application scenario is not suitable, consider using other methods to achieve it.

It is also important to note that when writing, it will copy a new container, so if there is a need for writing, it is best to write in batches, because the container will copy each time it is written. If you can reduce the number of writes, you can reduce the number of container copies.

Under the JUC package, the two methods that realize the idea of CopyOnWrite are CopyOnWriteArrayList & CopyOnWriteArraySet. This article focuses on explaining CopyOnWriteArrayList clearly.

CopyOnWriteArrayList

In CopyOnWriteArrayList, one thing to note is the add method:

Public boolean add (E e) {final ReentrantLock lock = this.lock; / / requires locking when writing. If it is not locked, n copies may be sent out by copy in multithreaded scenarios / / after locking, it can be guaranteed that only one thread is operating lock.lock () when writing; try {Object [] elements = getArray () Int len = elements.length; / / copy the original array Object [] newElements = Arrays.copyOf (elements, len + 1); / / add the elements to be added to the new array newElements [len] = e; / / point the reference to the original array to the new array setArray (newElements); return true } finally {lock.unlock ();}}

It needs to be locked when writing, but not added when reading.

Because reading the elements of the original array has no effect on the new array, adding a lock will increase the performance overhead.

Public E get (int index) {return get (getArray (), index);} for example:

CopyOnWrite is under the JUC package, so it ensures thread safety

Let's do a little demo verification:

@ Slf4jpublic class ArrayListExample {/ / Total number of requests public static int clientTotal = 5000; / / number of threads executing concurrently public static int threadTotal = 200; private static List list = new ArrayList (); public static void main (String [] args) throws Exception {ExecutorService executorService = Executors.newCachedThreadPool (); final Semaphore semaphore = new Semaphore (threadTotal); final CountDownLatch countDownLatch = new CountDownLatch (clientTotal); for (int I = 0; I

< clientTotal; i++) { final int count = i; executorService.execute(()->

{try {semaphore.acquire (); update (count); semaphore.release ();} catch (Exception e) {log.error ("exception", e);} countDownLatch.countDown ();}) } countDownLatch.await (); executorService.shutdown (); log.info ("size: {}", list.size ());} private static void update (int I) {list.add (I);}}

Above is the client request 5000 times, there are 200 threads requesting at the same time, I use the ArrayList implementation, let's take a look at the print result:

If it is thread safe, then the final result should be 5000. If you run it a few more times, you will find that the execution result of each program is different.

What if it's CopyOnWriteArrayList?

@ Slf4jpublic class CopyOnWriteArrayListExample {/ / Total number of requests public static int clientTotal = 5000; / / number of threads executing concurrently public static int threadTotal = 200; private static List list = new CopyOnWriteArrayList (); public static void main (String [] args) throws Exception {ExecutorService executorService = Executors.newCachedThreadPool (); final Semaphore semaphore = new Semaphore (threadTotal); final CountDownLatch countDownLatch = new CountDownLatch (clientTotal); for (int I = 0; I

< clientTotal; i++) { final int count = i; executorService.execute(()->

{try {semaphore.acquire (); update (count); semaphore.release ();} catch (Exception e) {log.error ("excepiton", e);} countDownLatch.countDown ();}) } countDownLatch.await (); executorService.shutdown (); log.info ("size: {}", list.size ());} private static void update (int I) {list.add (I);}} this is the end of the article on "how to implement CopyOnWrite of Java". Thank you for reading! I believe that everyone has a certain understanding of the knowledge of "how to achieve CopyOnWrite of Java". If you want to learn more knowledge, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report