java - 用于初始化磁盘状态的双重检查锁定

标签 java singleton lazy-initialization double-checked-locking

我正在尝试编写一段代码,允许我为每个 JVM 安装一个库(即从远程端点下载存档并将其解压缩到磁盘上)一次(每台机器可能有多个 JVM,但这不是重点)问题)。

我知道 DCL 的缺陷关于内存同步的技术,但我不确定在我的情况下是否应该担心这一点,因为我的状态位于磁盘上。

你能在下面的代码片段中找到任何竞争条件吗?我在标准库的文档中找不到有关文件系统操作的线程安全性的任何信息(嗯,某些方法明确保证是原子的,但对其余方法没有提及)。

public class LibraryInstaller {
    // singleton state
    private static AtomicBoolean IS_INSTALLED = new AtomicBoolean();

    // this method will be called hundreds of millions of times. I could remove this requirement but it would force me
    // to use a dirty hack (the justification for that is out of scope)
    public static void ensureInstalled() {
        // double-checked locking to allow faster access after the initial installation
        if (IS_INSTALLED.get()) return;

        synchronized (LibraryInstaller.class) {
            if (!IS_INSTALLED.get()) install();
        }
    }

    // takes several minutes
    private static void install() { 
        downloadLibraryAndUncompressOnDisk();
        IS_INSTALLED.set(true);    
    }
}

最佳答案

您可能遇到的问题是,当一个线程位于 install() 内部时,您可能会阻塞多个线程几分钟。不确定这会对您的申请产生什么影响。 但除此之外,您的代码应该可以正常工作,并且 IS_INSTALLED 的状态应该对所有线程都可见。

您甚至应该能够使用简单的私有(private)静态 volatile boolean 值IS_INSTALLED

关于java - 用于初始化磁盘状态的双重检查锁定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50613992/

相关文章:

c# - ASP.NET Web 服务中单例的行为是什么?

objective-c - 保留您访问过的单例有什么意义?

c# - 使用属性进行延迟初始化的方法

java - hibernate 延迟错误但我不想要这些数据

java - @Stateless Session Bean 充当@Singleton Bean

java - 如何修复非线程安全的延迟初始化 CXF 客户端工厂?

java - 用户输入的总分、平均分、最低分和最高分(条件控制结构)

java - 通过 Spark Streaming 从 Kafka 代理中的特定主题分区读取数据

java - 如何遍历 SparseArray?

java - 如何使用Java执行文件夹中的所有sql脚本?