Concurrent container based on copyonwritearraylist (example explanation)

Copyonwritearraylist concurrency container

Copy on write, referred to as cow, is an optimization strategy used in program design. The basic idea is that everyone is sharing the same content from the beginning. When someone wants to modify the content, he will really copy the content to form a new content and then change it. This is a delayed laziness strategy. From jdk1 5 starts Java and provides two concurrent containers implemented using copyonwrite mechanism in the contract. They are copyonwritearraylist and copyonwritearrayset. The copyonwrite container is very useful and can be used in many concurrent scenarios.

What is a copyonwrite container

The copyonwrite container is the container that is copied on write. The popular understanding is that when we add elements to a container, we do not directly add them to the current container, but first copy the current container, copy a new container, then add elements to the new container, and then point the reference of the original container to the new container after adding elements. The advantage of this is that we can read the copyonwrite container concurrently without locking, because the current container will not add any elements. Therefore, the copyonwrite container is also an idea of separating reading and writing. Reading and writing are different containers.

Implementation principle of copyonwritearraylist

Before using copyonwritearraylist, let's read its source code to understand how it is implemented. The following code is the implementation of the add method in copyonwritearraylist (adding elements to copyonwritearraylist). It can be found that locking is required when adding, otherwise N copies will be copied when writing by multiple threads.

There is no need to lock when reading. If multiple threads are adding data to the copyonwritearraylist when reading, the old data will still be read, because the old copyonwritearraylist will not be locked when writing.

Copyonwritemap is not provided in JDK. We can refer to copyonwritearraylist to implement one. The basic code is as follows:

The implementation is very simple. As long as we understand the copyonwrite mechanism, we can implement various copyonwrite containers and use them in different application scenarios.

Application scenario of copyonwrite

Copyonwrite concurrency container is used for concurrency scenarios with more reads and less writes. For example, the access and update scenarios of white list, blacklist and commodity categories. If we have a search website, users enter keywords in the search box of the website, but some keywords are not allowed to be searched. These keywords that cannot be searched will be placed in a blacklist, which will be updated every night. When users search, they will check whether the current keyword is in the blacklist. If it is, they will be prompted that they cannot search. The implementation code is as follows:

The code is simple, but there are two things to pay attention to when using copyonwritemap:

1. Reduce expansion overhead. Initialize the size of copyonwritemap according to actual needs to avoid the overhead of capacity expansion of copyonwritemap during writing.

2. Use batch add. Because the container will be copied every time it is added, reducing the number of additions can reduce the number of copies of the container. For example, use the addblacklist method in the above code.

Disadvantages of copyonwrite

Copyonwrite container has many advantages, but there are also two problems, namely, memory occupation and data consistency. So we need to pay attention to it when developing.

Memory usage problem. Because of copyonwrite's copy on write mechanism, when writing, the memory of two objects will be stationed in the memory at the same time, Old objects and newly written objects (Note: when copying, only the references in the container are copied, but when writing, new objects will be created and added to the new container, while the objects in the old container are still in use, so there are two copies of object memory). If these objects occupy a large memory, such as about 200m, then writing 100m data into it will occupy 300m, so it is very possible at this time Causing frequent Yong GC and full GC. Previously, we used a service in our system. Because the copyonwrite mechanism is used to update large objects every night, there is a full GC of 15 seconds every night, and the application response time becomes longer.

To solve the problem of memory occupation, you can reduce the memory consumption of large objects by compressing the elements in the container. For example, if the elements are all hexadecimal numbers, you can consider compressing them into hexadecimal 36 or hexadecimal 64. Or instead of using the copyonwrite container, use another concurrent container, such as concurrenthashmap.

Data consistency problem. Copyonwrite container can only guarantee the final consistency of data, but can not guarantee the real-time consistency of data. So if you want to write data that can be read immediately, please do not use the copyonwrite container.

The above concurrent container based on copyonwritearraylist (example explanation) is all the content shared by Xiaobian. I hope it can give you a reference and support more programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>