首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Brian的实践中,为什么不简单地使用computeIfAbsent呢?

在Brian的实践中,为什么不简单地使用computeIfAbsent呢?
EN

Stack Overflow用户
提问于 2022-09-28 08:01:51
回答 1查看 112关注 0票数 -1

Brian在实践中的Java并发性在pg 108:在Brian实际使用的Java并发中,为什么回形器类没有使用@ThreadSafe进行注释?上提供了一个回忆器的实现

下面的实现有哪些潜在的缺点,而不是这种(也许是过于复杂的实现)?

代码语言:javascript
复制
public class ConcurrentMemoizer<A, V> implements Computable<A, V> {

    private final ConcurrentMap<A, V> cache = new ConcurrentHashMap<>();
    private final Computable<A, V> c;

    public ConcurrentMemoizer(Computable<A, V> c) {
        this.c = c;
    }


    @Override
    public V compute(A arg) {
        return cache.computeIfAbsent(arg, a -> c.compute(a);
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-28 11:31:53

在Brian实际使用的Java并发中,为什么不简单地使用computeIfAbsent

如果你在问为什么这本书没有使用它,一个答案是,当这本书出版时,ConcurrentHashMap没有computeIfAbsent

如果您是在问为什么不应该使用它,原因就在于@Mark所指出的javadoc警告:

“在计算过程中,其他线程在此地图上的一些尝试更新操作可能会被阻止,因此计算应该简短而简单。”

说明:如果您查看典型的computeIfAbsent(key, function)实现中的ConcurrentHashMap源代码,您将看到它在key所在的子映射上持有一个锁。访问同一子映射中其他键的其他线程将被阻塞。如果对function的调用需要很长时间,这是有问题的。这本书也谈到了这个问题。

Goetz在第108页的最后版本使用了FutureTaskputIfAbsent来处理这个问题。阻塞时间是最小的,除非另一个线程试图获得当前计算的值。

“.为什么Memoizer类不带@ThreadSafe__注释?”

我想说这只是个疏忽。书中还有其他一些例子,其中没有用@ThreadSafe对线程安全类进行注释。(请注意,这些注释只是咨询性的。它们不能使代码线程安全。)

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

https://stackoverflow.com/questions/73878065

复制
相关文章

相似问题

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