Double checked locking with ConcurrentMap(使用 ConcurrentMap 进行双重检查锁定)
问题描述
我有一段代码可以由多个线程执行,它需要执行 I/O 绑定操作以初始化存储在 ConcurrentMap
中的共享资源.我需要使这个代码线程安全并避免不必要的调用来初始化共享资源.这是错误的代码:
I have a piece of code that can be executed by multiple threads that needs to perform an I/O-bound operation in order to initialize a shared resource that is stored in a ConcurrentMap
. I need to make this code thread safe and avoid unnecessary calls to initialize the shared resource. Here's the buggy code:
private ConcurrentMap<String, Resource> map;
// .....
String key = "somekey";
Resource resource;
if (map.containsKey(key)) {
resource = map.get(key);
} else {
resource = getResource(key); // I/O-bound, expensive operation
map.put(key, resource);
}
使用上面的代码,多个线程可能会检查 ConcurrentMap
并看到资源不存在,并且都尝试调用昂贵的 getResource()
.为了确保只对共享资源进行一次初始化并在资源初始化后使代码高效,我想做这样的事情:
With the above code, multiple threads may check the ConcurrentMap
and see that the resource isn't there, and all attempt to call getResource()
which is expensive. In order to ensure only a single initialization of the shared resource and to make the code efficient once the resource has been initialized, I want to do something like this:
String key = "somekey";
Resource resource;
if (!map.containsKey(key)) {
synchronized (map) {
if (!map.containsKey(key)) {
resource = getResource(key);
map.put(key, resource);
}
}
}
这是双重检查锁定的安全版本吗?在我看来,由于检查是在 ConcurrentMap
上调用的,因此它的行为类似于声明为 volatile
的共享资源,因此可以防止任何部分初始化"问题这可能会发生.
Is this a safe version of double checked locking? It seems to me that since the checks are called on ConcurrentMap
, it behaves like a shared resource that is declared to be volatile
and thus prevents any of the "partial initialization" problems that may happen.
推荐答案
是的,它很安全.
如果 map.containsKey(key)
为真,根据 doc,map.put(key, resource)
发生在它之前.因此 getResource(key)
发生在 resource = map.get(key)
之前,一切正常.
If map.containsKey(key)
is true, according to doc, map.put(key, resource)
happens before it. Therefore getResource(key)
happens before resource = map.get(key)
, everything is safe and sound.
这篇关于使用 ConcurrentMap 进行双重检查锁定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 ConcurrentMap 进行双重检查锁定
基础教程推荐
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 在螺旋中写一个字符串 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01