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
。
假设我有一个名为 map 的共享 ConcurrentHashMap
第一个线程执行这段代码:
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
。