假设这是一个“单一”实现:我是否保证只调用一次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";