为什么 ConcurrentHashMap.putifAbsent 是安全的?
我从昨天开始就一直在阅读并发性,但我知道的事情不多......但是有些事情开始变得清晰......
我理解为什么双重检查锁定不安全(我想知道罕见情况发生的概率是多少),但 volatile 解决了 1.5 + 中的问题....
但我想知道这种情况是否会发生在 putifAbsent
中,
例如...
myObj = new myObject("CodeMonkey");
cHashM.putIfAbsent("keyy",myObj);
那么这是否可以确保当另一个线程执行 cHashM.get() 时
???因为它可能有一个引用未完全初始化(双重检查锁问题)myObj
将 100% 初始化
I have been reading for concurency since yesterday and i dont know much things... However some things are starting to getting clear...
I understand why double check locking isnt safe (i wonder what is the propability the rare condition to occur) but volatile fixes the issue in 1.5 +....
But i wonder if this occurs with putifAbsent
like...
myObj = new myObject("CodeMonkey");
cHashM.putIfAbsent("keyy",myObj);
Then does this ensures that myObj
would be 100% intialiased when another thread does a cHashM.get()
??? Because it could have a reference isnt completely initialised (the double check lock problem)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您调用concurrentHashMap.get(key)并且它返回一个对象,则保证该对象被完全初始化。每个 put (或 putIfAbsent)将获得一个特定于存储桶的锁,并将该元素追加到存储桶的条目中。
现在您可能会浏览代码并注意到 get 方法没有获得相同的锁。因此,您可以说可能存在过时的读物,但这也不是事实。这里的原因是条目本身的值是不稳定的。因此,您一定会获得最新的阅读内容。
If you invoke
concurrentHashMap.get(key)
and it returns an object, that object is guaranteed to be fully initialized. Each put (or putIfAbsent) will obtain a bucket specific lock and will append the element to the bucket's entries.Now you may go through the code and notice that the get method doesnt obtain this same lock. So you can argue that there can be an out of date read, that isn't true either. The reason here is that value within the entry itself is volatile. So you will be sure to get the most up to date read.
ConcurrentHashMap
中的putIfAbsent
方法是 check-if-absent-then-set 方法。这是一个原子操作。但要回答以下部分:“那么这是否确保当另一个线程执行 cHashM.get() 时 myObj 将 100% 初始化”,这将取决于对象何时放入 HashMap 中。通常有一个发生之前的优先级,即,如果调用者在将对象放入映射之前首先获得,则将返回null
,否则将返回该值。putIfAbsent
method inConcurrentHashMap
is check-if-absent-then-set method. It's an atomic operation. But to answer the following part: "Then does this ensures that myObj would be 100% intialiased when another thread does a cHashM.get() ", it would depend on when the object is put into the HashMap. Usually there is a happens-before precedence, i.e., if the caller gets first before the object is placed in the map, thennull
would be returned, else the value would be returned.文档的相关部分是这样的:
--
java.util.ConcurrentMap< /code>
所以,是的,你有你的发生在关系。
The relevant part of the documentation is this:
--
java.util.ConcurrentMap
So, yes you have your happens-before relationship.
我不是这方面的专家,但是查看
ConcurrentHashMap
中Segment
的实现,我发现volatile
字段count< /code> 似乎用于确保线程之间的适当可见性。所有读取操作都必须读取
count
字段,所有写入操作都必须写入该字段。来自课堂上的评论:I'm not an expert on this, but looking at the implementation of
Segment
inConcurrentHashMap
I see that thevolatile
fieldcount
appears to be used to ensure proper visibility between threads. All read operations have to read thecount
field and all write operations have to write to it. From comments in the class: