看起来很傻,但我无法得到这个。 VolatileCachedFactorizer保留OneValueCache的实例并在每次调用中重新初始化它。不应该在同步块中完成此分配吗?
@Immutable
class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i, BigInteger[] factors) {
lastNumber = i;
lastFactors = Arrays.copyOf(factors, factors.length);
}
public BigInteger[] getFactors(BigInteger i) {
if (lastNumber == null || !lastNumber.equals(i))
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
public class VolatileCachedFactorizer implements Servlet {
private volatile OneValueCache cache =
new OneValueCache(null, null);
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
if (factors == null) {
factors = factor(i);
cache = new OneValueCache(i, factors); // is this line ok?
}
encodeIntoResponse(resp, factors);
}
}
答案 0 :(得分:1)
cache
变量为volatile
。这意味着对的写入操作发生在后续读取操作之前,该操作会观察到写入的值。因此,相关对象已安全发布到另一个线程,无需进一步同步。
请注意,由于OneValueCache
是一个不可变类,即使没有volatile("通过数据竞争&#34发布),代码仍然是线程安全的在一个线程的意义上,如果它曾经观察过一个对象,它将保证完全初始化它。但是,如果没有volatile
,则无法保证对象的引用将被另一个线程观察到。