同意`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) {
// Volatile读取
Object v = value;
if (v instanceof PendingValue) {
try {
lock.lock();
// 在获取锁后进行volatile读取,以防它已更改
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);
}
try {
lock.unlock();
}
}
return v;
}
} else {
return getOrThrow(unsynchronizedValue);
}
}
... // `force`, `isRealized`实现在此处
}
```