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

  • 由于原子putIfAbsent(),无尽的while循环在这里出现了吗?
  • 是否应在putIfAbsent()的impl内部而不是客户端代码中使用while循环?
  • while循环是否应该在较小范围内,仅包装putIfAbsent()?
  • 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());
            }
         }
       }
    }
    

    最佳答案

    1)由于原子putIfAbsent()而导致无尽的while循环在这里?

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

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

    不,请阅读putIfAbsent的功能。它仅尝试放置一个对象一次。

    3)while循环是否应该在较小范围内,只是包装putIfAbsent()?

    不,不应该。参见#1。

    4)while循环的可读性很差。

    您可以自由提供更好的东西。实际上,此构建套件非常适合需要尝试做某事直到成功进行的情况。

    07-24 21:51