仔细检查哈希图上的锁定 - 线程安全?



以下代码线程安全吗?类 SlidingTimeWindowCountGauge 已经是线程安全的。问题在于双重检查锁定代码+常规非并发哈希映射。

我想懒惰地在哈希图中创建条目。条目只应创建一次,此后应重复使用。如果可能的话,我想避免锁定。

public class InstrumentedCaller {
private final Map<String, SlidingTimeWindowCountGauge> nameToCountGauge = new HashMap<>();
private SlidingTimeWindowCountGauge getGaugeLazy(final String name) {
SlidingTimeWindowCountGauge gauge = nameToCountGauge.get(name);
if (gauge != null) {
return gauge;
}
synchronized (this) { 
if (nameToCountGauge.containsKey(name)) { 
return nameToCountGauge.get(name);
}
final SlidingTimeWindowCountGauge newGauge = new SlidingTimeWindowCountGauge(1, TimeUnit.MINUTES);
this.nameToCountGauge.put(name, newGauge);
return newGauge;
}
}
private void markCall(final String callName) {
SlidingTimeWindowCountGauge gauge = getGaugeLazy(callName);
gauge.mark();
}
public void doCall1() {
markCall("call1");
}
public void doCall2() {
markCall("call2");
}
}

使用ConcurrentHashMapcomputeIfAbsent正确实现getGaugeLazy的线程安全实现:

private final Map<String, SlidingTimeWindowCountGauge> nameToCountGauge = new ConcurrentHashMap<>();
private SlidingTimeWindowCountGauge getGaugeLazy(final String name) {
return nameToCountGauge.computeIfAbsent(name, k -> new SlidingTimeWindowCountGauge(1, TimeUnit.MINUTES));
}

请注意,编写起来也简单得多。

最新更新