多线程环境下ConcurrentHashMap方法执行顺序

ConcurrentHashMap method execution order in multithreaded environment

根据以下 JLS 规则- 线程中的每个操作都发生在该线程中按程序顺序稍后出现的每个操作之前。

在下面的情况下,clear() 是否总是在放入多线程环境之前执行

private ConcurrentMap<Feature, Boolean> featureMap = new ConcurrentHashMap<>();

public void loadAllConfiguration() {
    featureMap.clear();
    featureMap.put()
}

我不是很清楚这个问题,但我认为:

Each action in a thread happens-before every action in that thread that comes later in the program's order.

意味着在单个线程的上下文中(因为 clearput 正在阻塞同步调用)运行时保证它们将按照它们被调用的顺序执行。

根据我对 java 的有限理解,这不应扩展到多线程环境。假设您有一个在两个线程之间共享的并发映射,并且这些线程中的每一个都针对共享的 featureMap.

调用 loadAllConfiguration

线程可以并发执行,让操作交错!!!!

这可能导致执行顺序为:

**THREAD 1**                          **THREAD 2**
map.clear()
map.put()
                                     map.clear()
                                     map.put()

甚至在两个清除被同时调用然后两个放置被同时应用。


我没有使用过 java 所以我不确定 ConcurrentHashMap 提供了什么,但我假设它只会保护你免受竞争条件的影响(一个线程写入而另一个线程读取) 通过使用某种同步,但它仍然可能会让您暴露于逻辑错误(即 clears/put)以确定性方式交错)

In the below case, would clear() always execute before put in a multithreaded environment

是的,在多线程应用程序中,每个线程 clear()put() 之前。但是,当您查看 多个 线程的交互时,就共享 ConcurrentHashMap.

而言,情况不再如此

例如,由于竞争条件,您可能会看到以下事件序列:

  1. 线程 1 调用 clear()。
  2. 线程 2 调用 clear()。
  3. 线程 3 调用 clear()。
  4. 线程 2 调用 put()。
  5. 线程 1 调用 put()。
  6. 线程 3 调用 put()。

即使每个线程都清除然后放置,也不能保证 ConcurrentHashMap 中只有 1 个项目,如果那是您的问题所在。