Java 使用scala TrieMap更新concurrentMap是否需要替换while循环
在java中,我通常执行以下操作:Java 使用scala TrieMap更新concurrentMap是否需要替换while循环,java,scala,concurrency,Java,Scala,Concurrency,在java中,我通常执行以下操作: boolean done = false; while(!done) { Long oldValue = map.putIfAbsent(key, 1L); if(oldValue != null) { done = map.replace(key, oldValue, oldValue + 1); } else { done = true; } } 现在我看到,在scala中,我最好使用Tri
boolean done = false;
while(!done) {
Long oldValue = map.putIfAbsent(key, 1L);
if(oldValue != null) {
done = map.replace(key, oldValue, oldValue + 1);
} else {
done = true;
}
}
现在我看到,在scala中,我最好使用
TrieMap
(如果我坚持使用可变版本),我真的不知道这个TrieMap
中是否已经存在一个一次性操作,它将在循环时为我执行此操作,如果是,请给出一个示例?小心TrieMap
(至少是可变的),它实际上不是线程安全的。至少,它继承了getOrElseUpdate
的非线程安全实现。我没有检查其他方法(例如putIfAbsent
)是否也有同样的问题,但一个并发错误已经足够糟糕了
附录
我将把新的信息放在这里,而不是添加另一条评论
TrieMap.putIfAbsent
有一个特定于TrieMap
的实现,但它的value参数不是按名称参数,因此如果缓存的目的是避免昂贵的计算,它会再次失败!小心TrieMap
(至少是可变的),它实际上不是线程安全的。至少,它继承了一个非线程安全的getOrElseUpdate
实现。我没有检查其他方法(如putIfAbsent
)是否也有同样的问题,但一个并发错误已经够糟糕的了
附录
我将把新的信息放在这里,而不是添加另一条评论
TrieMap.putIfAbsent
有一个特定于TrieMap
的实现,但它的value参数不是一个按名称的参数,因此如果缓存的目的是避免昂贵的计算,它会再次失败!putIfAbsent
和replace
根据API是原子的,因此至少可以编写相同的代码ScalaDocs只是简单地说它是一个并发的线程安全类,但在getOrElseUpdate
(至少)被修复之前,这根本不是真的。是的,我同意,拥有一个带有公共方法的类是危险的(至少可以说),尽管它们看起来像(并且经常像)一样,但你永远都不能调用它你想要什么。但是,当他们说特定的方法是原子的时候,我倾向于相信他们。我不确定你想说什么。当前的实现公然违反了它的契约。我只知道这一点,因为我在尝试使用可变TrieMap
作为并发的并且看到了对给定键的getOrElseUpdate
的第二个参数的多次求值。它已损坏!(通过查看库代码也很容易看出原因。)使用promise
和putIfAbsent
似乎是一种方法。putIfAbsent
和replace
根据API是原子的,因此至少可以编写与java版本相同的代码。ScalaDocs简单地说它是一个并发的线程安全类,但直到getOrElseUpdate
(至少)是的,我同意(至少可以说)有一个带有公共方法的类是危险的,你永远都不需要调用它,尽管它们看起来像(而且经常像)你想要什么。但是,当他们说特定的方法是原子的时候,我倾向于相信他们。我不确定你想说什么。当前的实现公然违反了它的契约。我只知道这一点,因为我在尝试使用可变TrieMap
作为并发的系统并看到对给定键的getOrElseUpdate
的第二个参数进行了多次求值。它已损坏!(通过查看库代码也很容易看出原因。)使用promise
和putIfAbsent
似乎是一种方法。