public T get() {
// Another variant of Double Checked Locking.
//
// We use two volatile reads. We could reduce this to one by
// putting our fields into a holder class, but (at least on x86)
// the extra memory consumption and indirection are more
// expensive than the extra volatile reads.
long nanos = expirationNanos;
long now = Platform.systemNanoTime();
if (nanos == 0 || now - nanos >= 0) {
synchronized (this) {
if (nanos == expirationNanos) { // recheck for lost race
T t = delegate.get();
value = t;
nanos = now + durationNanos;
// In the very unlikely event that nanos is 0, set it to 1;
// no one will notice 1 ns of tardiness.
expirationNanos = (nanos == 0) ? 1 : nanos;
return t;
}
}
}
return value;
}
我不明白第二次检查的条件是“nanos == expirationNanos”,而不是“nanos == 0 || now - nanos> = 0”。如果名为threadA和threadB的两个线程调用get方法并同时转到同步代码,则threadA获取锁。当threadA执行所有代码并释放锁时,param expirationNanos'的值也等于nanos'的值。 ThreadB不能直接返回t实例,它也执行代码。如果条件为“nano == 0 || now-nanos> = 0”,则情况不会发生。
答案 0 :(得分:0)
如果第二次检查中的条件是nanos == 0 || now - nanos >= 0
,那么它总是正确的,因为它们是局部变量。另请注意,当expirationNanos
设置为nanos
时,nanos
之前已设置为now + durationNanos
。换句话说,当线程B进入同步块时,nanos == expirationNanos
应该不为真。