JDK8中的ConcurrentHashMap的死循環bug

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的其它節點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章