搜尋

首頁  >  問答  >  主體

java - ConcurrentHashMap的get为什么可以不加锁?

ringa_leeringa_lee2802 天前832

全部回覆(5)我來回復

  • 阿神

    阿神2017-04-18 10:08:21

    1. 內部實作用了鎖,你用它的時候就不需要再加一層鎖了

          『他都是复制出一个新的数组进行复制, 而非在原地操作』 你在哪里看到有复制的代码?

      2/3. 寫入沒完成的時候就讀,就會讀到null,此時鎖是被寫操作lock的,等待寫入操作unlock,再去讀就可以讀到了。

    回覆
    0
  • 阿神

    阿神2017-04-18 10:08:21

    1. get 不需要加鎖,只是讀取並不會對資料改變

    2. readValueUnderLock 正常情況不會被執行

    3. e.value 不会为 null 作者Doug Lea解釋如下

    Not quite. You are right that it should never be called. However, the JLS/JMM can be read as not absolutely forbidding it from being called because of weaknesses in required ordering relationships among finals vs volatiles set in constructors (key is final, value is volatile), wrt the reads by threads using the entry objects. (In JMM-ese, ordering constraints for finals fall outside of the synchronizes-with relation.) That's the issue the doc comment (pasted below) refers to. No one has ever thought of any practical loophole that a processor/compiler might find to produce a null value read, and it may be provable that none exist (and perhaps someday a JLS/JMM revision will fill in gaps to clarify this), but Bill Pugh once suggested we put this in anyway just for the sake of being conservatively pedantically correct. In retrospect, I'm not so sure this was a good idea, since it leads people to come up with exotic theories.

    在高版的jdk中ConncurrentHashMap已經完全重寫了,這部分程式碼也沒有了。

    回覆
    0
  • 黄舟

    黄舟2017-04-18 10:08:21

    ConncurrentHashMap 是jdk5引入的,它本身的操作就是確保了線程安全的,因此不需要加鎖了

    回覆
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:08:21

    經典讀寫模型,讀一般不用加鎖的

    回覆
    0
  • PHPz

    PHPz2017-04-18 10:08:21

    Get 操作並沒有對底層的陣列或鍊錶產生更改操作。樓主的疑問可能是Get的時候另一個線程同時put,或者get的時候另一個線程同時remove。其實這裡沒問題的 ,如果get在前put在後,那就get到null啦,如果get後remove在前,那也會拿到null啦。不會出現put在前反而get到null的情況或是remove再前反而拿到obj的情況。因為remove或put最終的操作就是原子的設定 segment[i].table[j]. get操作沒有機會對該操作搗亂

    回覆
    0
  • 取消回覆