gpt4 book ai didi

Java同步块(synchronized block)使用方法调用获取同步对象

转载 作者:行者123 更新时间:2023-11-30 05:58:37 25 4
gpt4 key购买 nike

我们正在编写一些锁定代码并遇到了一个奇怪的问题。我们使用 ConcurrentHashMap 来获取我们锁定的 Object 实例。所以我们的同步块(synchronized block)看起来像这样

synchronized(locks.get(key)) { ... }

我们重写了 ConcurrentHashMap 的 get 方法,使其在不包含键的情况下始终返回一个新对象。

@Override
public Object get(Object key) {
Object o = super.get(key);
if (null == o) {
Object no = new Object();
o = putIfAbsent((K) key, no);
if (null == o) {
o = no;
}
}
return o;
}

但是有没有一种状态,get-method返回了对象,但是线程还没有进入synchronized block 。允许其他线程获取同一对象并锁定它。

我们有一个潜在的竞争条件是

  • 线程1:获取key为A的对象,但没有进入synchronized block
  • 线程2:获取key为A的对象,进入同步块(synchronized block)
  • 线程 2:从映射中删除对象,退出同步块(synchronized block)
  • 线程1:进入synchronized block ,对象不再在map中
  • 线程 3:为键 A 获取一个新对象(与线程 1 获取的对象不同)
  • 线程 3:进入一个同步块(synchronized block),而线程 1 也在其同步块(synchronized block)中,两者都使用 key A

如果java在get调用返回后直接进入synchronized block ,就不会出现这种情况。如果没有,是否有人对我们如何删除 key 而不用担心这种竞争条件有任何意见?

最佳答案

在我看来,问题源于您锁定了映射值,而实际上您需要锁定(或一些派生的它)。如果我理解正确,您希望避免 2 个线程使用相同的 key 运行临界区。

你能锁定 key 吗?你能保证你总是使用相同的 key 实例吗?

一个不错的选择:

根本不要删除锁。使用ReferenceMap具有弱值。这样,只有当前未被任何线程使用时,映射条目才会被删除。

注意:

1) 现在您必须同步此 map (使用 Collections.synchronizedMap(..))。

2) 您还需要同步为给定键生成/返回值的代码。

关于Java同步块(synchronized block)使用方法调用获取同步对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4134980/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com