这个代码来自Java Concurrency实践中的ThreadSafe吗?

时间:2014-08-02 18:27:00

标签: java concurrency

看起来很傻,但我无法得到这个。 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);
        }
    }

1 个答案:

答案 0 :(得分:1)

cache变量为volatile。这意味着对的写入操作发生在后续读取操作之前,该操作会观察到写入的值。因此,相关对象已安全发布到另一个线程,无需进一步同步。

请注意,由于OneValueCache是一个不可变类,即使没有volatile("通过数据竞争&#34发布),代码仍然是线程安全的在一个线程的意义上,如果它曾经观察过一个对象,它将保证完全初始化它。但是,如果没有volatile,则无法保证对象的引用将被另一个线程观察到。