Java concurrency Programming: the Copyonwritearraylist of concurrent containers

Source: Internet
Author: User

This article transferred from: http://www.cnblogs.com/dolphin0520/p/3938914.html

Java Concurrency Programming: copyonwritearraylist of Concurrent Containers (reprint)

Original link:

http://ifeve.com/java-copy-on-write/

  

Copy-on-write abbreviation Cow, is a kind of optimization strategy used in program design. The basic idea is that from the beginning everyone is sharing the same content, when someone wants to modify the content, it will really copy the content to form a new content and then change, this is a delay lazy strategy. Starting with JDK1.5 Java Concurrency Package provides two concurrent containers implemented using the Copyonwrite mechanism, which are copyonwritearraylist and Copyonwritearrayset. The Copyonwrite container is very useful and can be used in very many concurrent scenarios.

What is a copyonwrite container

The Copyonwrite container is the container that is copied when it is written. The popular understanding is that when we add elements to a container, instead of adding them directly to the current container, the current container is copied, a new container is duplicated, the new container is added, the element is added, and the reference to the original container is pointed to the new container. The advantage of this is that we can read the Copyonwrite container concurrently, without having to lock it, because the current container does not add any elements. So the Copyonwrite container is also a reading and writing separation of ideas, reading and writing different containers.

The realization 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 to the Copyonwritearraylist (add elements to the copyonwritearraylist), you can find that when added is required to lock, or multithreaded writing will copy out n copies out.

1234567891011121314151617181920 /**     * Appends the specified element to the end of this list.     *     * @param e element to be appended to this list     * @return <tt>true</tt> (as specified by {@link Collection#add})     */    publicbooleanadd(E e) {    finalReentrantLock lock = this.lock;    lock.lock();    try {        Object[] elements = getArray();        intlen = elements.length;        Object[] newElements = Arrays.copyOf(elements, len + 1);        newElements[len] = e;        setArray(newElements);        returntrue;    finally{        lock.unlock();    }    }

There is no need to lock when reading, if more than one thread is adding data to copyonwritearraylist at the time of reading, read or read the old data, because the writing will not lock the old copyonwritearraylist.

123 publicE get(int index) {    returnget(getArray(), index);}

The JDK does not provide copyonwritemap, we can refer to Copyonwritearraylist to implement one, the basic code is as follows:

123456789101112131415161718192021222324252627282930313233 importjava.util.Collection;importjava.util.Map;importjava.util.Set;publicclassCopyOnWriteMap<K, V> implementsMap<K, V>, Cloneable {    privatevolatileMap<K, V> internalMap;     publicCopyOnWriteMap() {        internalMap = newHashMap<K, V>();    }    publicV put(K key, V value) {        synchronized(this) {            Map<K, V> newMap = newHashMap<K, V>(internalMap);            V val = newMap.put(key, value);            internalMap = newMap;            returnval;        }    }    publicV get(Object key) {        returninternalMap.get(key);    }    publicvoidputAll(Map<? extendsK, ? extendsV> newData) {        synchronized(this) {            Map<K, V> newMap = newHashMap<K, V>(internalMap);            newMap.putAll(newData);            internalMap = newMap;        }    }}

Implementation is simple, as long as we understand the copyonwrite mechanism, we can implement a variety of copyonwrite containers, and used in different scenarios.

Copyonwrite's application Scenario

Copyonwrite concurrent containers are used for read-write-less concurrency scenarios. such as white list, blacklist, product category to visit and update the scene, if we have a search site, users in this Site search box, enter keywords search content, but some keywords are not allowed to be searched. These keywords that cannot be searched are placed in a blacklist, and the Blacklist is updated every night. When the user searches, it checks that the current keyword is not in the blacklist, and if so, the prompt cannot be searched. The implementation code is as follows:

1234567891011121314151617181920212223242526272829303132333435 packagecom.ifeve.book;importjava.util.Map;importcom.ifeve.book.forkjoin.CopyOnWriteMap;/** * 黑名单服务 * * @author fangtengfei * */publicclassBlackListServiceImpl {    privatestatic CopyOnWriteMap<String, Boolean> blackListMap = newCopyOnWriteMap<String, Boolean>(            1000);    publicstaticbooleanisBlackList(String id) {        returnblackListMap.get(id) == nullfalsetrue;    }    publicstaticvoidaddBlackList(String id) {        blackListMap.put(id, Boolean.TRUE);    }    /**     * 批量添加黑名单     *     * @param ids     */    publicstaticvoidaddBlackList(Map<String,Boolean> ids) {        blackListMap.putAll(ids);    }}

The code is simple, but there are two things to note about using Copyonwritemap:

1. Reduce the expansion overhead. According to the actual needs, initialize the size of the copyonwritemap to avoid the overhead of copyonwritemap expansion when writing.

2. Use bulk Add. Because each time it is added, the container replicates every time, so you can reduce the number of times the container replicates by reducing the number of additions. such as using the Addblacklist method in the above code.

Disadvantages of Copyonwrite

The Copyonwrite container has many advantages, but there are also two problems, namely, memory occupancy and data consistency. So in the development of the time need to pay attention.

memory consumption issues . Because of the copyonwrite of the write-time replication mechanism, so when the write operation, memory will be stationed at the same time the memory of two objects, the old object and the newly written object (note: In the copy is copied only the reference in the container, but at the time of writing will create a new object to add to the new container, The object of the old container is still in use, so there are two copies of the object memory. If these objects occupy a large amount of memory, say 200M or so, then write 100M data in, memory will occupy 300M, then this time is likely to cause frequent Yong GC and full GC. Before we used a service in our system because the copyonwrite mechanism is used to update large objects every night, resulting in a full GC of 15 seconds per night, the application response time also becomes longer.

For memory usage, you can reduce the memory consumption of large objects by compressing the elements in the container, for example, if the elements are all 10 binary numbers, consider compressing them into 36 or 64 binary. Or do not use the Copyonwrite container, but use other concurrent containers, such as Concurrenthashmap.

data consistency issues . The Copyonwrite container can only guarantee the final consistency of the data and cannot guarantee the real-time data consistency. So if you want to write the data that can be read right away, please do not use the Copyonwrite container.

  

The following article verifies the performance of copyonwritearraylist and the synchronization container:

http://blog.csdn.net/wind5shy/article/details/5396887

The following article briefly describes the use of copyonwritearraylist:

http://blog.csdn.net/imzoer/article/details/9751591

Java concurrency Programming: copyonwritearraylist of concurrent Containers (RPM)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.