实践5.19中的Java并发

yin*_*ing 6 java concurrency

在JCIP书中,清单5.19存储器的最终实现。我的问题是:

  1. 由于原子putIfAbsent(),无尽的while循环在这里出现了吗?
  2. while循环是否应该放在putIfAbsent()的impl内部而不是客户端代码?
  3. 仅将putIfAbsent()包装起来,while循环是否应处于较小范围内?
  4. while循环的可读性差

码:

public class Memorizer<A, V> implements Computable<A, V> {
    private final ConcurrentMap<A, Future<V>> cache
            = new ConcurrentHashMap<A, Future<V>>();
    private final Computable<A, V> c;
    public Memorizer(Computable<A, V> c) { this.c = c; }
    public V compute(final A arg) throws InterruptedException {
    while (true) { //<==== WHY?
        Future<V> f = cache.get(arg);
        if (f == null) {
           Callable<V> eval = new Callable<V>() {
               public V call() throws InterruptedException {
                    return c.compute(arg);
               }
           };
           FutureTask<V> ft = new FutureTask<V>(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());
        }
     }
   }
}
Run Code Online (Sandbox Code Playgroud)

tcb*_*tcb 4

1) 无限的 while 循环是因为原子 putIfAbsent() 造成的?

这里的 while 循环用于在取消计算时重复计算(中的第一种情况try)。

2) while 循环应该在 putIfAbsent() 的 impl 内部而不是客户端代码中吗?

不,请阅读内容putIfAbsent。它只是尝试只放置一个对象一次。

3) while 循环应该在更小的范围内,只包装 putIfAbsent() 吗?

不,不应该。参见#1。

4)While循环在可读性上看起来很糟糕。

你可以自由地提供更好的东西。事实上,这个构建套件非常适合您必须尝试做某事直到成功为止的情况。