【问题标题】:Memory consistency effects in ConcurrentMapConcurrentMap 中的内存一致性效果
【发布时间】:2018-01-02 17:14:14
【问题描述】:

根据ConcurrentMap Javadoc

内存一致性效果:与其他并发集合一样,线程中在将对象作为键或值放入 ConcurrentMap 之前的操作happen-before 在访问或删除对象之后的操作该对象来自另一个线程中的ConcurrentMap

上面的语句是什么意思?当ConcurrentHashMap 中的get() 方法没有阻塞(例如与BlockingQueue 相比)时,它是如何工作的?

【问题讨论】:

  • 我注意到您尚未接受任何答案。请考虑在某个时候这样做!

标签: java multithreading concurrency


【解决方案1】:

意思很简单。假设你有两段代码:

 a = new A();
 b = ...
 someConcurrentHashMap.put(b, whatever);

然后:

Whatever value = someConcurrentHashMap.get(b);
c = new C();

b同一个对象并且这两段代码由两个不同的线程执行时,那么保证a = new A()发生之前 c = new C()

有关“发生在之前”的进一步阅读 - 请参阅here

对于实现细节,我建议您研究源代码code - 包含 tons 的(非 javadoc!) cmets,这些 cmets 解释了此类的内部工作原理。

【讨论】:

    【解决方案2】:

    GhostCat 已经解释了happens-before 的含义。但是,可能值得注意的是这与“阻塞”之间的区别。

    在阻塞队列中,试图从队列中轮询的线程将等待直到有可用的东西。

    对于ConcurrentHashMap 之类的东西,情况并非如此。简单的happens-before关系意味着您在将其添加到地图之前所做的一切在其他线程访问它时仍然发生。但这并不意味着其他线程会等待具有给定密钥的东西可用。

    举一个重要的例子,考虑两个类 foo 和 bar。在 Foo 的构造函数中,我们将其添加到 Bar 中的列表中。现在我们把这个 Foo 的实例放在ConcurrentHashMap 中并在另一个线程中访问它。合乎逻辑的是,我们对 Foo 的那个实例所做的一切仍然发生了。但是,Java 也会确保 Foo 的实例仍然被添加到 Bar 中的列表中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-21
      • 2019-01-17
      • 1970-01-01
      • 2012-09-09
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多