gpt4 book ai didi

java - LazyReference 具有双重检查锁定和 null 处理

转载 作者:行者123 更新时间:2023-12-01 17:35:52 25 4
gpt4 key购买 nike

我使用 LazyReference 类已有几年了(当然不是定期使用,但有时它非常有用)。类(class)可见here 。感谢 Robbie Vanbrabant(类(class)作者)和 Joshua Bloch 的著名“Effective Java 2nd edt”。 (原始代码)。

该类可以正常工作(在 Java 5+ 中),但存在一个潜在的小问题。如果 instanceProvider 返回 null (当然,它不能根据 Guice Provider.get() 契约,但是......),然后在每次执行 时>LazyReference.get() 方法将保留 LOCK,并且会一遍又一遍地调用 instanceProvider.get。对于那些违反契约(Contract)的人来说,这看起来是一个很好的惩罚(嘿嘿),但如果真的需要延迟初始化一个可以设置 null 值的字段怎么办?

我稍微修改了 LazyReference:

public class LazyReference<T> {

private final Object LOCK = new Object();

private volatile T instance;

private volatile boolean isNull;

private final Provider<T> instanceProvider;

private LazyReference(Provider<T> instanceProvider) {
this.instanceProvider = instanceProvider;
}

public T get() {
T result = instance;
if (result == null && !isNull) {
synchronized (LOCK) {
result = instance;
if (result == null && !isNull) {
instance = result = instanceProvider.get();
isNull = (result == null);
}
}
}
return result;
}
}

恕我直言,它应该工作得很好(如果您有其他意见,请发表您的评论和批评)。但我想知道如果我从 isNull boolean 值中删除 volatile 修饰符(当然将其留给实例)会发生什么?它还能正常工作吗?

最佳答案

上面的代码有一个竞争条件:在设置 isNull 之前,instance 可能会从 instanceProvider.get() 的结果设置为“真正的”null。

您确定放弃这些复杂的废话并正确同步对您来说不会更容易吗?我敢打赌您将无法测量性能的任何差异,并且会更容易验证您的代码是否正确。

关于java - LazyReference 具有双重检查锁定和 null 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6444823/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com