假设这是一个“单一”实现:我是否保证只调用一次productCatalogLoader.load(),并且没有空指针发生?有什么办法可以简化这个过程?

private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private ProductCatalog productCatalog;

public ProductCatalog get() {
        if (this.productCatalog == null) {
            reload();
         }
        return this.productCatalog;
}

public void reload() {

    lock.writeLock().lock();
    try {
        if (this.productCatalog != null) return;
        this.productCatalog = productCatalogLoader.load();
    } finally {
        lock.writeLock().unlock();
    }
}


}

编辑:
这是一次不大成功的尝试,将更多复杂的代码简化为一个简单的问题样本。有几个人发现我的单例太复杂了;)(实际上,还有一个石英计时器调用reload,但是“ reload”实现与IRL有点不同)。无论如何,我得到了我需要的答案,打破了双重检查锁定。

最佳答案

看起来像broken double checked locking。问题是this.productCatalog可以在对象完全构造之前分配。

说我们有

var foo = new ProductCatalog();
foo.blah = "blah blah";
this.productCatalog = foo;


可以重新排序为

var foo = new ProductCatalog();
this.productCatalog = foo;
foo.blah = "blah blah";

10-05 22:41