面试刷题10:ConcurrentHashMap如何保证线程安全…
2020-03-25 16:11:54来源:博客园 阅读 ()
面试刷题10:ConcurrentHashMap如何保证线程安全?
集合框架中的HashTable,Stack,以及同步包装集合在高并发场景下都非常低效,java提供了并发包应对高并发场景。
我是李福春,我在准备面试,今天的问题是?
java提供了哪些并发的容器?ConcurrentHashMap如何保证线程安全?
java体系中的并发容器
java体系中有如下同步容器:
1, HashTable,Stack 同步容器,内部使用sychronized关键字保证同步操作;
2,同步包装器Collections.synchronizedMap(),内部也使用sychronized关键字保证同步操作;
3,并发包提供的同步容器,比如ConcurrentHashMap , CopyOnWriteArrayList , ArrayBlockingQueue,SynchronizedQueue
ConcurrentHashMap的同步分析
为何会出现ConcurrenHashMap?
1, HashTable在高并发场景下性能低下;
2,HashMap 不是线程安全的容器;
3,同步包装器虽然使用同步方法快提升了部分性能,但是还是不适合高并发场景下的性能需求;
接下来回答问题,ConcurrentHashMap如何保证线程安全?
java7
java7版本使用的是分离锁(segment)实际上是一种再入锁(RetrantLock)来保证线程安全;
segment的数量是concurrentLevel决定,默认值是16;
扩容的时候是针对单个segment扩容的,写操作也是,修改数据的时候锁定的部分,所以比较高效;
但是后去size可能不太准确。
数据结构如下图:
java8
java8中segment依然存在,不过不起结构上的作用,只起到保证序列化的兼容性。
内部使用volatile来保证数据存储的可见性;
利用CAS操作,在特定场景下进行无锁并发操作,内部的锁实际用的是syncronized;
因为在jdk8中,syncronized已经得到性能的优化,并且对比再入锁可以减少内存消耗。
见代码:
final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh; K fk; V fv;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
// 利用CAS去进行无锁线程安全操作,如果bin是空的
if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value)))
break;
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else if (onlyIfAbsent // 不加锁,进行检查
&& fh == hash
&& ((fk = f.key) == key || (fk != null && key.equals(fk)))
&& (fv = f.val) != null)
return fv;
else {
V oldVal = null;
synchronized (f) {
// 细粒度的同步修改操作...
}
}
// Bin超过阈值,进行树化
if (binCount != 0) {
if (binCount >= TREEIFY_THRESHOLD)
treeifyBin(tab, i);
if (oldVal != null)
return oldVal;
break;
}
}
}
addCount(1L, binCount);
return null;
}
小结
本节回答了java提供的并发容器分类,以及ConcurrentHashMap在java7,java8中的是如何保证线程安全的。
面试官喜欢问分离锁,画一下数据结构就明确了。
原创不易,转载请注明出处。
原文链接:https://www.cnblogs.com/snidget/p/12567580.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 2020年深圳中国平安各部门Java中级面试真题合集(附答案) 2020-06-11
- JVM常见面试题解析 2020-06-11
- 作为一个面试官,我想问问你Redis分布式锁怎么搞? 2020-06-10
- 送你一份年薪百万的抖音Java岗内部面试题 2020-06-09
- 一口气说出 6种 延时队列的实现方案,面试稳稳的 2020-06-08
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash