-
為什么ConcurrentHashMap是線程安全的
JDK1.7中,ConcurrentHashMap使用的鎖分段技術,將數據分成一段一段的存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。 -
那說說JDK1.7中Segment的原理
剛剛說的一段一段就是指Segment,它繼承了ReentrantLock,具備鎖和釋放鎖的功能。ConcurrentHashMap只有16個Segment,並且不會擴容,最多可以支持16個線程並發寫。 -
JDK1.8的ConcurrentHashMap怎么實現線程安全的
JDK1.8放棄了鎖分段的做法,采用CAS和synchronized方式處理並發。以put操作為例,CAS方式確定key的數組下標,synchronized保證鏈表節點的同步效果。 -
JDK1.8的做法有什么好處呢
- 減少內存開銷
假設使用可重入鎖,那么每個節點都需要繼承AQS,但並不是每個節點都需要同步支持,只有鏈表的頭節點(紅黑樹的根節點)需要同步,這無疑消耗巨大內存。 - 獲得JVM的支持
可重入鎖畢竟是API級別的,后續的性能優化空間很小。synchronized則是JVM直接支持的,JVM能夠在運行時作出相應的優化措施:鎖粗化、鎖消除、鎖自旋等等。使得synchronized能夠隨着JDK版本的升級而不改動代碼的前提下獲得性能上的提升。
- 減少內存開銷
-
為什么不推薦使用HashTable呢
HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下。因為多個線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,並且也不能使用get方法來獲取元素,所以競爭越激烈效率越低。
參考(部分摘抄的文字版權屬於原作者):
https://segmentfault.com/a/1190000015907000
https://www.cnblogs.com/zhaojj/p/8942647.html
https://www.cnblogs.com/wfq9330/p/9606472.html