java - 使用 ConcurrentMap 双重检查锁定

标签 java concurrency synchronization double-checked-locking

我有一段代码可以由多个线程执行,该代码需要执行 I/O 绑定(bind)操作,以便初始化存储在 ConcurrentMap 中的共享资源。我需要使这段代码线程安全,并避免不必要的调用来初始化共享资源。这是有错误的代码:

    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() ,这是昂贵的。为了确保共享资源仅进行一次初始化,并在资源初始化后使代码高效,我想做这样的事情:

    String key = "somekey";
    Resource resource;
    if (!map.containsKey(key)) {
        synchronized (map) {
            if (!map.containsKey(key)) {
                resource = getResource(key);
                map.put(key, resource);
            }
        }
    }

这是双重检查锁定的安全版本吗?在我看来,由于检查是在 ConcurrentMap 上调用的,因此它的行为就像被声明为 volatile 的共享资源,从而防止任何“部分初始化”问题这可能会发生。

最佳答案

如果你可以使用外部库,看看Guava的MapMaker.makeComputingMap() 。它是为您想要做的事情量身定制的。

关于java - 使用 ConcurrentMap 双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61514288/

相关文章:

c++ - 用于线程间通信的 volatile 和 mutex

concurrency - Perl 6 中是否有快速并行 "for"循环?

c++ - 以线程安全的方式与外界共享一个数据成员

java - 如何处理GXT 2.2网格中单元格的点击?

java - 使用递归 Java 反转行

java - 将消息传递给间接相关的参与者

Java:多个线程通过同步方法同时访问变量递减静态变量

安卓进程同步

java - 如何在android中使用SLF4j获取日志文件

java - 如何从 Eclipse 插件中启动 "import maven project"?