20并发容器
List
CopyOnWriteArrayList
写的时候将共享变量复制一份,好处是读操作完全无锁
写操作:新复制数组上增加元素后再将array指向这个新的数组
Map
ConcurrentHashMap key无序 k/v都不可为空 线程安全
ConcurrentSkipListMap key有序 k/v都不可为空 线程安全
HashMap k/v 都允许为空 线程不安全
TreeMap k/v k不可空,v可空 线程不安全
HashTable k/v 都不可空 线程安全
SkipList 插入、删除、查询操作平均的时间复杂度是 O(logn)
跳表理论上和并发线程数没关系,在并发度非常高时,若对ConcurrentHashMap性能不满意,可尝试ConcurrentSkipListMap,并发线程数越高跳表结构的优势越明显.
Set
CopyOnWriteArraySet
ConcurrentSkipListSet
参考CopyOnWriteArrayList、ConcurrentSkipListMap原理一致
Queue
最复杂的并发容器类
分维度分类:
- 维度1-阻塞/非阻塞
队列满时入队是否阻塞,空时出队是否阻塞;阻塞队列都用Blocking关键字标识 - 维度2-单端/双端
单端指的是只能队尾入队,队首出队;Queue标识
双端指的是队首队尾皆可入队出队;Deque标识
是否有界内部队列容量是否有限,无界队列易导致OOM不建议使用
单端阻塞队列
数组实现 ArrayBlockingQueue 有锁结构
链表实现 LinkedBlockingQueue 有锁结构
无队列 SynchronousQueue
LinkedBlockingQueue + SynchronousQueue = LinkedTransferQueue ,CAS无锁结构
优先级队列 PriorityBlockingQUeue
延迟队列 DelayQueue
SynchronousQueue
take线程阻塞直到有put的线程放入元素为止,反之亦然
//⽤于存储所有的数据库连接
CopyOnWriteArrayList
//线程本地存储中的数据库连接
ThreadLocal<List
双端阻塞队列
LinkedBlockingDeque
单端非阻塞队列
ConcurrentLinkedQueue
双端非阻塞队列
ConcurrentLinkedDeque
总结
理清楚每种容器的特性
ArrayBlockingQueue 和 LinkedBlockingQueue支持有界,其他无界,注意无界队列导致OOM
问题
容器的Fail-Fast(快速失败)机制什么是
concurrentskiplistmap比concurrenthashmap性能好
concurrentskiplistmap没有key冲突问题,HashMap key冲突通过链表或者tree解决所以O(1)是理想状态。增删改操作也影响hashmap性能,要看冲突情况。所以hashmap的稳定性差,如果正好遇到稳定性问题无法接受可尝试ConcurrentSkipListMap