0
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;
}
我不明白的地方第二次检查的条件是“毫微== expirationNanos”,而不是“毫微秒== 0 ||现在 - 毫微> = 0”。如果两个名为threadA和threadB的线程同时调用get方法并进入同步代码,threadA将获得该锁。当threadA执行所有代码并释放锁定时,param expirationNanos的值也等于nanos的值。 ThreadB不能直接返回t实例,它也会执行代码。如果条件是“nano == 0 || now-nanos> = 0”,情况就不会发生。ExpiringMemoizingSupplier的方法实施名为Get
虽然'nanos'设置为'now + durationNanos',expirationNanos也设置为'(nanos == 0)? 1:nanos'。换句话说,当线程B进入同步块时,'nanos == expirationNanos'应该为真。如果'nanos == now + durationNanos; expirationNanos ==(nanos == 0)? 1:nanos'被修改了'expirationNanos == now + durationNanos;',那会好起来的。 –
我认为你可能误解了一些东西。请记住'nanos'是一个局部变量;线程B具有与线程A不同的值。当线程B进入时,'nanos == expirationNanos'应该为false。 – ColinD
我明白了,非常感谢你~~^_ ^ –