java - ConcurrentHashMap的get为什么可以不加锁?
ringa_lee
ringa_lee 2017-04-18 10:06:21
0
5
825
ringa_lee
ringa_lee

ringa_lee

全部回复(5)
阿神
  1. 内部实现用了锁,你用它的时候就不需要再加一层锁了

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

    2/3. 写入没完成的时候就读,就会读到null,此时锁是被写操作lock的,等待写操作unlock,再去读就可以读到了。

阿神
  1. get 无需加锁,只是读取并不会对数据发生改变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

🎜readValueUnderLock 正常情况不会被执行🎜 🎜🎜e.value 不会为 null 作者Doug Lea解释如下🎜 rrreee 🎜在高版本的jdk中ConncurrentHashMap已经完全重写了,这部分代码也没有了。🎜
黄舟

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

Peter_Zhu

经典读写模型,读一般不用加锁的

PHPzhong

Get 操作并没有对底层的数组或者链表产生更改操作。楼主的疑问可能是Get的时候另一个线程同时put,或者get的时候另一个线程同时remove。其实这里没问题的 ,如果get在前put在后,那就get到null啦,如果get后remove在前,那也会拿到null啦。不会出现put在前反而get到null的情况或者remove再前反而拿到obj的情况。因为remove或者put最终的操作就是原子的设置 segment[i].table[j]. get操作没有机会对该操作捣乱

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板