【问题标题】:How to synchronize on equal keys from different objects in Java如何在Java中不同对象的相等键上同步
【发布时间】:2021-02-20 20:21:21
【问题描述】:

calculate 方法在不同线程上执行多次。然后将其结果保存到HashMap。类似的东西:

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

Data calculate(Key key){
     ...
}

我想防止对同一个键的多次执行,但我不想阻塞所有线程。理想的解决方案是将calculate 同步到Key。问题是Key不是最终的,我可以比较键并检查它们是否相等,但它们将是不同的对象。

我该如何解决这个问题?

【问题讨论】:

标签: java hashmap synchronization


【解决方案1】:

看起来您可以使用ConcurrentMap 实现(例如ConcurrentHashMap),然后让computeIfAbsent 完成繁重的工作:

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

【讨论】:

    【解决方案2】:

    根据文档,computeIfAbsent 可能是乐观的。如果你需要一个悲观的解决方案,你可以使用条带锁。因此,您创建了一个可以锁定的对象数组以及找到锁定的键的哈希。

    private final Object[] locks = ....
    
    synchronized(lock(key)){
        ...
    }
    
    Object lock(Object key){
          return locks[hashToIndex(key.hashcode())]
    }
    

    【讨论】:

    • 我喜欢这个想法,但您有两个挑战需要解决:如何处理哈希冲突?如何清理未使用的密钥?
    • 如果发生碰撞,您只需阻止。所以让数组足够大,这样碰撞的机会就很小了。在上面的示例中,没有存储任何密钥,因此没有需要删除的未使用密钥。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多