【问题标题】:is there a replacement for while loop for update of concurrentMap with scala TrieMap有没有替代while循环来更新concurrentMap with scala TrieMap
【发布时间】:2014-01-22 15:18:25
【问题描述】:

在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 中我最好使用 TrieMap(如果我坚持使用可变版本)我真的不明白这个 TrieMap 中是否已经存在一次性操作这个while循环给我,如果可以,你能举个例子吗?

【问题讨论】:

    标签: java scala concurrency


    【解决方案1】:

    小心TrieMap(至少是可变的),它实际上不是线程安全的。至少,它继承了getOrElseUpdate 的非线程安全实现。我没有检查其他方法(例如putIfAbsent)是否有同样的问题,但是一个并发错误已经足够糟糕了!

    附录

    我不会添加其他评论,而是将新信息放在这里...

    TrieMap.putIfAbsent 有一个特定于TrieMap 的实现但是它的值参数不是一个别名参数,所以如果缓存的目的是为了避免昂贵的计算,它又失败了!

    【讨论】:

    • putIfAbsentreplace 根据 API 是原子的,所以至少你可以编写与 java 版本相同的代码。
    • ScalaDocs 简单地说它是一个并发和线程安全的类,但直到getOrElseUpdate(至少)被修复,这根本不是真的。
    • 是的,我同意拥有一个具有公共方法的类是危险的(至少可以说),尽管它们看起来像(并且经常表现得像)你想要的那样,但你永远不必调用它们。不过,当他们说特定方法是原子的时,我倾向于相信他们。
    • 我不确定你想说什么。当前的实施公然违反了其合同。我只知道这一点,因为当我尝试使用可变 TrieMap 作为并发系统中的缓存并看到对给定键的 getOrElseUpdate 的第二个参数进行多次评估时,我亲眼目睹了失败。它被打破! (通过查看库代码也很容易理解原因。)
    • 使用promiseputIfAbsent 似乎是一种方式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-13
    • 2012-05-22
    相关资源
    最近更新 更多