Java 具有不可变值的ConcurrentHashMap-同步替换?

Java 具有不可变值的ConcurrentHashMap-同步替换?,java,immutability,concurrenthashmap,Java,Immutability,Concurrenthashmap,我在多线程程序中使用ConcurrentHashMap。映射将serverid映射到包含有关服务器的更多信息的对象(无论服务器是否联机,最近使用了多少等)。ServerID和ServerInformation都是不可变的 为了更新服务器信息,我正在或多或少地执行此问题中建议的B)点: 即(修改为使用我自己的变量名)如下: 现在我的问题是:是否应该同步此方法以排除丢失更新的可能性 还是有其他方法可以实现这一点?可能类似于以下内容(根据我的原始版本进行编辑,以删除一个明显的错误): 是的,替换方法

我在多线程程序中使用ConcurrentHashMap。映射将serverid映射到包含有关服务器的更多信息的对象(无论服务器是否联机,最近使用了多少等)。ServerID和ServerInformation都是不可变的

为了更新服务器信息,我正在或多或少地执行此问题中建议的B)点:

即(修改为使用我自己的变量名)如下:

现在我的问题是:是否应该同步此方法以排除丢失更新的可能性

还是有其他方法可以实现这一点?可能类似于以下内容(根据我的原始版本进行编辑,以删除一个明显的错误):


是的,替换方法是解决这个问题的正确方法。只需记住在您的值对象上适当地覆盖相等

(这假设计算newValue相对便宜,冲突相对较少。如果这是一个密集的计算,并且冲突很常见,那么引入互斥并序列化计算可能是值得的。)


最好是将作业重新提交到为线程提供服务的任何队列,或者将其放入延迟队列,而不是实际将工作线程置于睡眠状态。睡眠工作线程总体上是令人悲伤的,缺乏可伸缩性。

线程。睡眠
是对失败的
替换
的错误响应;相反,您应该重做计算:重做
serverMap.get(id)
,重做
addUsage
。您当然是对的!否则,替代者可能永远不会成功。。。修改我的问题以反映你的建议有意义吗?对不起,我是新来的。。。
public void addUsage(ServerID id, long moreUsage) {
    ServerInfo oldInfo = serverMap.get(id);
    ServerInfo newInfo = oldInfo.addUsage(moreUsage);
    serverMap.put(id, newInfo);
}
public void addUsage(ServerID id, long moreUsage) {
    ServerInfo oldInfo = serverMap.get(id);
    ServerInfo newInfo = oldInfo.addUsage(moreUsage);
    while (!serverMap.replace(id, oldInfo, newInfo) ) {
        oldInfo = serverMap.get(id);
        newInfo = oldInfo.addUsage(moreUsage);
        // try again later
        Thread.sleep(SOME_TIME);
    };
}