5

How do copy on write collections provide thread-safety and in which scenarios are they useful to implement?

prvn
  • 684
  • 6
  • 21
  • Note that copy-on-write can also avoid ConcurrentModificationExceptions within a single thread. – Thilo Sep 21 '15 at 09:38
  • 1
    http://javamex.com/tutorials/synchronization_concurrency_8_copy_on_write.shtml – Thilo Sep 21 '15 at 09:41

2 Answers2

3

CopyOnWriteArrayList

An instance of CopyOnWriteArrayList behaves as a List implementation that allows multiple concurrent reads, and for reads to occur concurrently with a write. The way it does this is to make a brand new copy of the list every time it is altered.

  1. Reads do not block, and effectively pay only the cost of a volatile read.
  2. Writes do not block reads (or vice versa), but only one write can occur at once.
  3. Unlike ConcurrentHashMap, write operations that write or access multiple elements in the list (such as addAll(), retainAll()) will be atomic.

During a write operation, the array must be locked completely against other writes. (The standard implementation uses a ReentrantLock.) However, this does mean that as mentioned, operations affecting multiple locations can be atomic. That is, if one thread adds several items to the list with addAll() while another thread calls size(), the thread reading the size will get a value that either reflects or not the number of elements added in addAll(): there'll be no possibility of an intermediate value returned (provided of course that these are the only two threads accessing the list!).

CopyOnWriteArrayList is designed for cases where reads hugely outnumber writes.

CopyOnWriteArraySet

Another class, CopyOnWriteArraySet is build on top of CopyOnWriteArrayList. Like its list counterpart, it is designed for cases where the set contains only a few elements and where reads greatly outnumber writes.

Reference: Java copy-on-write collections

YoungHobbit
  • 13,254
  • 9
  • 50
  • 73
  • How does locking mechanism work in this case? For instance If a thread iterates through the list ,reading the items in the list then it would had acquired the lock on the list object and during its acquisition of the lock how could other thread read it?? How come reads are not blocking?? – prvn Sep 21 '15 at 09:51
  • For reading it does not acquire the lock. The lock is used only when any update is happening on the array. – YoungHobbit Sep 21 '15 at 09:58
  • The [get()](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/CopyOnWriteArrayList.java#CopyOnWriteArrayList.get%28int%29) method does not have any lock where as [set()](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/concurrent/CopyOnWriteArrayList.java#CopyOnWriteArrayList.set%28int%2Cjava.lang.Object%29) first acquire the lock then processed. – YoungHobbit Sep 21 '15 at 10:02
  • But should not all the accesses to the data be synchronized? – prvn Sep 21 '15 at 10:05
  • What will be advantage you will get out of it then. The regular LinkedList can be use with synchronization in its existing implementation. – YoungHobbit Sep 21 '15 at 10:11
1

The way it does this is to make a brand new copy of the list every time it is altered.

Reads do not block, and effectively pay only the cost of a volatile read. Writes do not block reads (or vice versa), but only one write can occur at once.