【问题标题】:ConcurrentHashMap retrieval operation does not take lock?ConcurrentHashMap 检索操作不取锁?
【发布时间】:2013-05-06 09:44:06
【问题描述】:

根据 Java 文档

检索操作(包括get)一般不会阻塞,因此可能与更新重叠 操作(包括放置和删除)。检索反映了最近完成的更新操作在其开始时保持的结果。对于 putAll 和 clear 等聚合操作,并发检索可能仅反映插入或删除某些条目

问题:假设一个线程 t1 正在更新一个键值对(称为 x),然后另一个线程 t2 来并想要读取 x,是否会在 t2 和 t2 开始时创建 x 的副本 c1从该副本中读取 c1

【问题讨论】:

    标签: java multithreading concurrenthashmap


    【解决方案1】:

    问题:假设一个线程 t1 正在更新一个键值对(称为 x),然后另一个线程 t2 来并想要读取 x,是否会在 t2 和 t2 开始时创建 x 的副本 c1从该副本中读取 c1

    这取决于。如果 T1 的操作完成,T2 将看到该值。否则,T2 将看到旧值。

    来自http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html

    检索反映了最近完成的更新操作在开始时保持的结果。对于 putAll 和 clear 等聚合操作,并发检索可能仅反映插入或删除某些条目

    【讨论】:

    • 否则,T2 将看到旧值。 - 但从哪里可以看到,因为旧值不再存在(它正在更新中)
    • @Naroji 旧值将一直存在,直到 T1 更新它。这就是文档中“完成”的含义。希望这会有所帮助。
    • 感谢您的意见。如果是这样的话,那么 old_value 替换成 new_value 就是一个原子操作(CAS)吧?
    • @JavaGeek 是的,它必须是原子的并且对其他线程可见;否则这整个文档将毫无用处
    【解决方案2】:

    检索反映最近完成的更新的结果 手术开始后持续进行

    完成的单词在这里很重要。现在你的场景是

     Suppose a thread t1 is updating a key-value pair(called x), and then other thread t2 comes and want to read x.
    

    T2 将读取已完成且不在进程中的操作更新的值。在您的场景中,如果线程 t1 的更新操作未完成,t2 将看不到更新的值。不创建副本。其简单的时间基础。如果到 t2 线程读取 x 值并且 t2 更新操作完成,它将看到更新的值,否则看不到。

    【讨论】:

    • '否则不行。' - 从哪里 t2 将看到,因为旧值不再存在(它正在更新过程中)当 t2 到达读取时
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    相关资源
    最近更新 更多