ConcurrentHashMap put() 方法可以不是线程安全的吗?

Can ConcurrentHashMap put() method be not thread-safe?

假设我有一个名为 map 的共享 ConcurrentHashMap,它只有一个映射 ("One", 1),并且还假设我有 2 个线程。

第一个线程执行这段代码:

map.put("One", 2);

第二个线程执行这段代码:

synchronized (map) {
    Integer number = map.get("One");
    System.out.println(number == map.get("One"));
}

由于 ConcurrentHashMap 使用锁定条带化方法而不是锁定整个对象,因此我认为所描述的场景不是线程安全的。 特别是我不知道在第一个线程中 Integer number = map.get("One"); 调用和第二个线程中的 System.out.println(number == map.get("One")); 调用之间是否存在 map.put("One", 2); 的交错,尽管两者都在同步块中。

那么该代码是否可能打印错误?

ConcurrentHashMap 中的所有方法可能是线程安全的,但这并不意味着它在 ConcurrentHashMap 对象本身上同步。您可以做的是同步 put 和同一参考上的地图访问代码。您的 put 代码必须更改为:

synchronized (map) {
    map.put("One", 2);
}

您的访问代码可以保持为:

synchronized (map) {
    Integer number = map.get("One");
    System.out.println(number == map.get("One"));
}

这将永远无法打印 false