在Brian Goetz的Java Concurrency In Practice中

Brian Goetz的Java Concurrency实践提供了一个用于并发使用的高效可伸缩缓存的示例。 这是该类的代码:

public class Memoizer implements Computable { private final ConcurrentMap<A, Future> cache = new ConcurrentHashMap<A, Future>(); private final Computable c; public Memoizer(Computable c) { this.c = c; } public V compute(final A arg) throws InterruptedException { while (true) { Future f = cache.get(arg); if (f == null) { Callable eval = new Callable() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask ft = new FutureTask(eval); f = cache.putIfAbsent(arg, ft); if (f == null) { f = ft; ft.run(); } } try { return f.get(); } catch (CancellationException e) { cache.remove(arg, f); } catch (ExecutionException e) { throw launderThrowable(e.getCause()); } } } } 

可能是一个愚蠢的问题但是有人告诉我同时使用这个类吗? 喜欢在主?

干杯,Agata

以下是计算阶乘的示例:

 public static void main(String[] args) throws Exception { //create a memoizer that performs factorials final Memoizer memo = new Memoizer (new Computable() { @Override public Integer compute(Integer a) { int result = 1 ; for(int i = 1 ; i < a ; i++){ result = result*i; } return result; } }); //now call the memoizer System.out.println(memo.compute(10)); //call it with 10 threads concurrently ExecutorService exec = Executors.newFixedThreadPool(10); ExecutorCompletionService compService = new ExecutorCompletionService(exec); for(int i = 0 ; i < 15 ; i++){ compService.submit(new Callable(){ @Override public Integer call() throws Exception { return memo.compute(5); } }); } exec.shutdown(); for(int i = 0 ; i < 15 ; i++){ System.out.println(compService.take().get()); } } 

因此,如果两个线程试图在完全相同的时间计算相同的阶乘,则只有其中一个实际执行计算,因为putIfAbsent是线程安全的。 第二个线程将简单地获取第一个线程放在地图中的未来并等待它完成。

我可以想象这样的事情:

 class PrimeDetector implements Computable { public Boolean compute(BigInteger number) { // detect whether the number is prime and return true if it is } } Memoizer primeMemoizer = new Memoizer(new PrimeDetector()); boolean isPrime = primeMemoizer.compute( new BigInteger("5625945193217348954671586615478165774647538956473535")); ...