美文网首页
《Java 并发编程实战》P40的疑惑

《Java 并发编程实战》P40的疑惑

作者: nicaima | 来源:发表于2019-03-03 19:10 被阅读0次

    一、问题

    @Immutable
    public class OneValueCache {
    
        // final
        private final BigInteger lastNumber;
        private final BigInteger[] lastFactors;
    
        // Arrays.copyOf
        public OneValueCache(BigInteger lastNumber, BigInteger[] lastFactors) {
            this.lastNumber = lastNumber;
            this.lastFactors = Arrays.copyOf(lastFactors, lastFactors.length);
        }
    
        // Arrays.copyOf
        public BigInteger[] getFactors(BigInteger i) {
            if (lastNumber == null || !lastNumber.equals(i)) {
                return null;
            } else {
                return Arrays.copyOf(lastFactors, lastFactors.length);
            }
        }
    }
    
    @ThreadSafe
    public class VolatileCacheFactorizer {
    
        private volatile OneValueCache cache = new OneValueCache(null, null);
    
        /**
         * 疑问:有没有可能一个线程在cache.getFactors(i)时,判断相等要取值时,
         * 另一个线程new新的OneValueCache。
         *
         * 《Java 并发编程实战》P40原文:如果是一个不可变对象,那么当线程
         *  获得了对该对象的引用后,就不必担心另一个线程会修改对象的状态。
         *
         */
        public void service(Request request, Response response) {
            BigInteger i = extractFromRequest(request);
            BigInteger[] factors = cache.getFactors(i);
            if (factors == null) {
                factors = factor(i);
                cache = new OneValueCache(i, factors);
            }
            encodeIntoResponse(response, factors);
        }
    }
    

    疑问点:有没有可能一个线程在cache.getFactors(i)时,判断相等要取值时,另一个线程new新的OneValueCache。

    二、解惑

    注意当线程A执行cache.getFactors(i)时,如果判断了可以取这个缓存,那么此时这个cache对象就是安全的,因为另一个线程B是new的新的OneValueCache对象,线程A在执行cache.getFactors(i)时,老的OneValueCache对象并没有被GC掉。所以是线程安全的。当线程B执行完时,其他对象通过volatile看到新的cache。

    通过使用包含多个状态变量的容器对象来维持不变性条件,并使用一个volatile类型的引用来确保可见性,使得VolatileCachedFactorizer在没有显式地使用锁的情况下仍然是线程安全的。

    相关文章

      网友评论

          本文标题:《Java 并发编程实战》P40的疑惑

          本文链接:https://www.haomeiwen.com/subject/ceemuqtx.html