同意关于`synchronized`的观点。
对于可能出现的并发错误的观察很到位。以下是相关代码。尤其是`deref`使用了`volatile`/非同步策略。
```
public class Delay implements IDeref, IPending {
volatile Object value;
Object unsynchronizedValue;
ReentrantLock lock;
private static class ExceptionalValue {
private final Object v;
public ExceptionalValue (Object v) {
this.v = v;
}
}
private static class PendingValue {
private final Object v;
public PendingValue (Object v) {
this.v = v;
}
}
public Delay(IFn f){
Object v = new PendingValue(f);
unsynchronizedValue = v;
value = v;
lock = new ReentrantLock();
}
private static Object getOrThrow(Object v) {
if (v instanceof ExceptionalValue) {
return Util.sneakyThrow((Throwable)(((ExceptionalValue)v).v));
} else {
return v;
}
}
public Object deref() {
if (unsynchronizedValue instanceof PendingValue) {
// 可见性读取
Object v = value;
if (v instanceof PendingValue) {
try {
lock.lock();
// 在持有锁后进行可见性读取,以防它已更改
Object vAfter = value;
if (vAfter instanceof PendingValue) {
IFn f = (IFn)(((PendingValue)vAfter).v);
Object vComputed = null;
try {
vComputed = f.invoke();
} catch (Throwable t) {
vComputed = new ExceptionalValue(t);
}
unsynchronizedValue = vComputed;
value = vComputed;
return getOrThrow(vComputed);
} else {
return getOrThrow(vAfter);
}
} finally {
lock.unlock();
}
} else {
return v;
}
} else {
return getOrThrow(unsynchronizedValue);
}
}
... // 在此处实现`force`, `isRealized`
}
```