多线程之copyonwrite
多线程之copyonwrite
类似于Hashmap的线程安全实现,CurrentHashMap
针对List, Set, JUC提供了Copy-On-Write
容器CopyOnWriteArrayList
和CopyOnWriteArraySet
。
COW
COW的基本思路:
- 当读取共享数据时,直接读取,不需要有其他操作(比如阻塞等待、复制等)。
- 当写共享数据时,将旧数据复制出来一份作为新数据,只修改新数据,修改完新数据之后将新数据的引用赋值给原来数据的引用。在整个写数据的过程中,所有读取共享数据的操作都是读的旧数据。
COW容器只有写操作与写操作之间是互斥的,读读和读写都不互斥。
优缺点
优点:
- 效率高。因为COW保证读和写操作的不是同一份数据,共享数据在读和写时都不需要阻塞其他来读取数据的线程,所以COW有很高的效率。
- 保证数据一致性。因为COW保证读和写操作的不是同一份数据,读数据的操作不会读到写了一半的数据,所以能够保证数据的最终一致性。
缺点:
- 数据实时性差。COW在写数据完成之前一直读取旧数据,而写数据又包括复制和修改的操作,花费时间较长,导致数据实时性较差。其实COW的设计思想就是通过牺牲数据的实时性来保证数据一致性的。
- 内存占用大。COW中有一步复制操作,将旧数据复制出来一份作为新数据,假如旧数据本身比较大,那么新数据也要占用同样大的内存空间。类似空间换时间的思想,这里用空间换数据一致性,当然也换取了读取数据的时间。
code
add
public boolean add(E e) { |
应用
Copy-On-Write并发容器用于读多写少的并发场
举例:一个充值排行榜的功能,排行榜会有很多人查看访问,但是只有充值之后才会修改排行榜上的数据,或者充值之后也不更新,只有每天晚上9点更新排行榜,标准的读多写少。
summary
Implement mutability by creating and republishing a new copy of the collection every time it is modified.
The iterators returned by the copy-on-write collections do not throw ConcurrentModificationException
and return the elements exactly as they were at the time the iterator was created, regardless of subsequent modifications.
The copy-on-write collections are reasonable to use only when iteration is far more common than modification.
This criterion exactly describes many event-notification systems: delivering a notification requires iterating the list of registered listeners and calling each one of them, and in most cases registering or unregistering an event listener is far less common than receiving an event notification.