Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/401.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实践中的Java并发:清单3.12和3.13_Java_Multithreading_Concurrency - Fatal编程技术网

实践中的Java并发:清单3.12和3.13

实践中的Java并发:清单3.12和3.13,java,multithreading,concurrency,Java,Multithreading,Concurrency,我们有这些目标: //清单3.12 @Immutable class OneValueCache { private final BigInteger lastNumber; private final BigInteger[] lastFactors; public OneValueCache(BigInteger i, BigInteger[] factors) { lastNumber = i; lastFactors = Arra

我们有这些目标:

//清单3.12

@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);
        }
   }
}
//清单3.13

@ThreadSafe
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);
        }
        encodeIntoResponse(resp, factors);
    }
}
书中说VolatileCachedFactorizer是线程保存。为什么?

例如:

  • 线程A读取缓存.getFactors(i)
  • 然后线程B读取缓存
  • 然后线程B写入缓存
  • 然后线程写入缓存

  • 这个流可以被认为是线程保存吗?我不明白什么?

    简短回答:

    线程安全并不是绝对的。您必须确定所需的行为,然后询问实现是否为您提供了在多线程情况下所需的行为

    更长的回答:

    那么,这里想要的行为是什么?是因为总是给出正确的答案,还是因为如果两个线程连续请求它,它总是只实现一次

    如果是后者——也就是说,如果你真的想节省每一点CPU——那么你是对的,这不是线程安全的。两个请求可以同时进入(或足够接近)以获得相同数字N的因子,如果计时成功,两个线程可能最终都会计算该数字

    但是使用单值缓存,您已经有了重新计算已知内容的问题。例如,如果再次出现三个请求,例如N、K和N,该怎么办?对K的请求将使N处的缓存无效,因此您必须重新计算它

    因此,这个缓存确实针对相同值的“条纹”进行了优化,因此,在该条纹中两次计算前几对(甚至很少!)答案的成本可能是可以接受的:作为回报,您得到的代码没有任何阻塞,并且非常容易理解


    重要的是它永远不会给你错误的答案。也就是说,如果同时请求N和K,那么K的响应永远不会给出N的答案。这个实现为您提供了保证,所以我称之为线程安全。

    这是线程安全。最终目标是确保
    服务
    方法输出正确。OneValueCache始终保持
    lastNumber
    lastFactors
    之间的正确关系