JDK1.8中,其內部實現發生了較大變化,內部不再使用Segment鎖,而是使用synchronized + CAS(Unsafe類)方式來實現對map的每個Node的細粒度鎖控制。
其computeIfAbsent存在一個問題:
Map<String, Integer> map = new ConcurrentHashMap<>(16);
map.computeIfAbsent(
"AaAa",
key -> {
return map.computeIfAbsent(
"BBBB",
key2 -> 42);
}
);
https://stackoverflow.com/questions/43861945/deadlock-in-concurrenthashmap
這裏的“AaAa”和“BBBB”的hashCode一樣,會出現代碼死循環
這這篇文章解釋說是CAS造成的,因爲synchronized是可重入的鎖,但是爲什麼CAS會造成這個問題,我不認同他的說法。
https://www.jianshu.com/p/59bd27e137e1
總之,在JDK1.8中,不要在computeIfAbsent的lambda函數參數中再去更新map的其它節點。