如何在Java中对来自不同对象的相等键进行同步

如何在Java中对来自不同对象的相等键进行同步,java,hashmap,synchronization,Java,Hashmap,Synchronization,方法calculate在不同的线程上执行多次。然后将其结果保存到HashMap中。诸如此类: void execute(){ ... map.put(key, calculate(key); } Data calculate(Key key){ ... } 我想防止在同一个密钥上执行多次,但我不想阻止所有线程。理想的解决方案是在键上同步计算。问题是键不是最终的,我可以比较键并检查它们是否相等,但它们将是不同的对象 如何解决这个问题?看起来您可以使用一个实现(例如

方法
calculate
在不同的线程上执行多次。然后将其结果保存到
HashMap
中。诸如此类:

void execute(){
     ...
     map.put(key, calculate(key);
}

Data calculate(Key key){
     ...
}
我想防止在同一个密钥上执行多次,但我不想阻止所有线程。理想的解决方案是在
键上同步
计算
。问题是
不是最终的,我可以比较键并检查它们是否相等,但它们将是不同的对象


如何解决这个问题?

看起来您可以使用一个实现(例如),然后让我们来完成繁重的工作:

map.computeIfAbsent(key, k -> calculate(k));

根据文档,ComputeFabSent可能是乐观的。如果需要悲观的解决方案,可以使用条带锁。因此,您可以创建一个可以锁定的对象数组和密钥哈希来查找锁

private final Object[] locks = ....

synchronized(lock(key)){
    ...
}

Object lock(Object key){
      return locks[hashToIndex(key.hashcode())]
}

也许是
computeFabSent
!?我喜欢这个想法,但您需要解决两个挑战:如何处理哈希冲突?如何清理未使用的密钥?如果发生冲突,您只需阻塞即可。因此,使阵列足够大,以便碰撞的机会非常小。在上面的示例中,没有存储任何密钥,因此没有要删除的未使用密钥。