1, what is a write-time copy (Copy-on-write) container?
Write-time replication refers to: In the context of concurrent access, when it is necessary to modify the containers elements in Java, do not directly modify the container, but first copy a copy, the copy is modified. After the modification is complete, point to the original container's reference to the new container (the replica container).
2, the impact of copying when writing
① because the original container is not modified, only the replica container is modified. Therefore, the original container can be read concurrently. Secondly, the separation between the read operation and the write operation is realized, and the read operation occurs on the original container, and the write operation occurs on the replica container.
② Data Consistency issue: the thread of the read operation may not immediately read the newly modified data because the modification occurred on the replica. However, the final modification operation completes and updates the container, so this is final consistency.
3, the Copyonwritearraylist class and the Copyonwritearrayset class are provided in the JDK, but the implementation of the COPYONWRITEMAP is not provided. Therefore, you can refer to copyonwritearraylist yourself to achieve a copyonwritehashmap
Here is the main implementation of the write operation, how to ensure thread safety.
Importjava.util.Collection;ImportJava.util.HashMap;ImportJava.util.Map;ImportJava.util.Set; Public classCopyonwritemap<k, v>ImplementsMap<k, v>, cloneable{Private volatileMap<k, v>Internalmap; PublicCopyonwritemap () {Internalmap=NewHashmap<k, v> (100);//The initial size should be specified according to the actual application} @Override Publicv put (K key, V value) {synchronized( This) {Map<k, v> newmap =NewHashmap<k, v> (INTERNALMAP);//copy a new HashMapV val = newmap.put (key, value);//to perform a write operation in a new HashMapInternalmap = Newmap;//point the original map reference to the new map returnVal; }} @Override Public voidPutall (map<?extendsK?extendsV>m) {synchronized( This) {Map<k, v> newmap =NewHashmap<k, v>(INTERNALMAP); Newmap.putall (m); Internalmap=Newmap; }} @Override Publicv Get (Object key) {v result=Internalmap.get (key); returnresult; } ...//other methods inherit from interface Map
}
As can be seen from the above, lock is required for put () and Putall (). The read operation is not required, such as Get (Object key). Thus, when a thread needs to put a new element, it locks the current Copyonwritemap object and copies a new HashMap, while the other read threads can continue to access the original HashMap because they do not need to be locked.
4, Application Scenario
The Copyonwrite container is suitable for scenes with less read-write. Because of the need to replicate a container when writing, the memory overhead is significant and the initial container size needs to be grasped based on the actual application.
Not suitable for strong consistency of data. It is not possible to use the copy-on-write technique if it is required to be read immediately after data modification. Because it is final consistency.
Summary: Write-time replication technology is a good way to improve concurrency.
Resources:
Talk about Copy-on-write containers in concurrent-java
Java Collection Series 10 HashMap details (source parsing) and usage examples
Java Write-time replication (copy-on-write) Map implementation