7. 并发容器
7.1 并发容器概览
ConcurrentHashMap:线程安全的HashMap
CopyOnWriteArrayList:线程安全的List
BlockingQueue:阻塞队列接口,适合用于数据共享的通道
ConcurrentLinkedQueue:高效的非阻塞并发队列,可以看做线程安全的LinkedList
7.2 并发容器的历史
Vector 与 Hashtable 都是 JDK1.0时代的产物,使用 synchronized 来保证集合操作线程安全,也是并发初学者能想到的实现线程安全集合的方式。
Vector 是线程安全的 ArrayList,使用 synchronized 来保证线程安全,但是因为添加和取出操作都是用同一把锁,导致效率低下,现在 Vector 这个集合已经被淘汰。
// Vector使用sync来保证添加、删除、获取元素操作的线程安全,效率很低
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
public synchronized E remove(int index) {
// ......
elementData[--elementCount] = null; // Let gc do its work
return oldValue;
}
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
与之类似的还有 Hashtable,是线程安全的HashMap,也是使用 synchronized 来保证线程安全,效率低下已被淘汰。(需要注意Hashtable中T小写)
7.3 ConcurrentHashMap
为什么 HashMap 是线程不安全的?
- 同时put 碰撞导致数据丢失,两个线程put时,槽中没有数据,同时将数据插入某一个槽,后者会覆盖前者
- 同时put 扩容导致数据丢失
- 死循环造成 CPU 100%
7.3.1 CPU 100%问题
在JDK7中,HashMap 在扩容时容易出现死循环造成 100% 问题,具体分析参考下面文章
coolshell.cn/articles/96… www.jianshu.com/p/1e9cf0ac0… www.jianshu.com/p/619a8efcf… blog.csdn.net/loveliness_… cloud.tencent.com/developer/a… www.cnblogs.com/developer_c… www.yuque.com/dangxianyuy…
map why hashmap分析 1.7与1.8 也不是线程安全 案例
集合历史过时并发容器 ConcurrentHashMap CopyOnWriteArrayList 并发队列 总结