通常情況下,你可以使用putIfAbsent
這樣的:
final AtomicInteger present = map.get(tag);
int count;
if (present != null) {
count = present.incrementAndGet();
} else {
final AtomicInteger instance = new AtomicInteger(0);
final AtomicInteger marker = map.putIfAbsent(tag, instance);
if (marker == null) {
count = instance.incrementAndGet();
} else {
count = marker.incrementAndGet();
}
}
的原因明確get
之中,要避免分配「開心」路徑中的默認值(即,當已經有給定鍵的條目時)。
如果沒有匹配的條目,你必須使用順序putIfAbsent
返回值
之間
- 該條目仍下落不明區分(默認值爲已添加由於呼叫)在這種情況下,該方法返回
null
和
- 其他線程已經贏得了比賽,並插入調用
get
後的新條目(在這種情況下,該方法返回與給定鍵關聯的當前值)
你可以抽象這個序列通過引入一個輔助方法,例如,
interface Supplier<T> {
T get();
}
static <T> T computeIfAbsent(ConcurrentMap<K,T> map, T key, Supplier<? extends T> producer) {
final T present = map.get(key);
if (present != null) {
return present;
} else {
final T fallback = producer.get();
final T marker = map.putIfAbsent(key, fallback);
if (marker == null) {
return fallback;
} else {
return marker;
}
}
}
你可以在你的榜樣使用:
static final Supplier<AtomicInteger> newAtomicInteger = new Supplier<AtomicInteger>() {
public AtomicInteger get() { return new AtomicInteger(0); }
};
void yourMethodWhatever(Object tag) {
final AtomicInteger counter = computeIfAbsent(cancelretryCountMap, tag, newAtomicInteger);
if (counter.incrementAndGet() > 10) {
... whatever ...
}
}
注意,這實際上是已經在JDK 8作爲default
方法Map
,但由於您仍在使用JDK 7,因此您必須自行開發,就像這裏所做的那樣。