jdk并发容器整理(yet)

1.CopyOnWrite

写少读多的场景

读-读  读-写 写-读  不阻塞

写-写阻塞

写时复制,为什么复制?为了迭代器等遍历读操作的安全与性能,同String

set中看似比较多余的一句,背后的目的是什么,涉及到happens-before,多线程下volatile防止指令重排,确保可见性

数据读,总量读,迭代器符合最终一致性

2.ConcurrentLinkedQueue

无界,线程安全的LinkedList

基于CAS

tail最终一致

size最终一致

3.BlockingQueue

无界:LinkedBlockingQueue,有界:ArrayBlockingQuere

线程池默认四种类型用无界阻塞队列

基于重入锁

两种BQ有何区别

size强一致

产生最终一致的根本原因是:

写不阻塞读,读时不加锁,也没用volatile确保一个线程(节点)的写入立即对其它线程(节点)的读可见(concurrenthashmap是典型案例), 即失去线程间的可见性,读给历史版本(比如CLQ的size,Mysql的MVCC),或者根本是两样东西(CopyOnWrite)

写的东西非volatile(ConcurrentHashMap 的get和迭代器)



原文地址:https://www.cnblogs.com/silyvin/p/9106640.html