首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实践中的java并发性5.19

实践中的java并发性5.19
EN

Stack Overflow用户
提问于 2012-12-20 22:29:33
回答 2查看 479关注 0票数 8

在JCIP书中,清单5.19最终实现了内存程序。我的问题是:

  1. 由于原子putIfAbsent(),这里有无休止的while循环吗?
  2. 应该让putIfAbsent()内部的while循环代替客户端代码吗?
  3. while循环是否应该在较小的范围内,只需要包装putIfAbsent()?
  4. 循环的可读性很差。

代码:

代码语言:javascript
运行
复制
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());
        }
     }
   }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-20 23:42:34

1)由于原子putIfAbsent()的存在,这里有无穷无尽的while循环吗?

这里的while循环用于在取消计算时重复计算(try中的第一个例子)。

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

不,请读一下putIfAbsent做了什么。它只试着放置一个物体一次。

3) while循环应该在较小的范围内仅包装putIfAbsent()吗?

不,不应该。见第一。

4)循环的可读性不佳。

你可以自由地提供更好的东西。事实上,当你不得不尝试做一些事情直到它成功的时候,这个建筑套房是非常适合的情况。

票数 4
EN

Stack Overflow用户

发布于 2012-12-20 22:45:50

不,不能缩小while循环的范围。您希望对缓存中的值执行f.get()。如果映射中没有arg的值,则希望对结果执行get(),否则要获得映射中的argget()的现有值。

问题是这个实现中没有锁,所以在检查是否有值和试图插入值之间,另一个线程可能已经插入了自己的值。同样,在插入失败和检索之间,可以将值从缓存中删除(由于一个CancellationException)。由于这些故障情况,您可以在while(true)中旋转,直到您可以将规范值从映射中提取出来,或者将一个新值插入到映射中(使您的值规范化)。

您似乎可以尝试将更多的f.get()从循环中移出,但是由于存在CancellationException的风险,因此您需要继续尝试。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13981595

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档