Normalerweise würden Sie putIfAbsent
wie folgt verwenden:
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();
}
}
Der Grund für die explizite get
Wesen, dass Sie die Zuordnung vermeiden möchten von der Standardwert im "Happy" -Pfad (dh wenn bereits ein Eintrag mit dem angegebenen Schlüssel vorhanden ist).
Wenn kein entsprechender Eintrag vorhanden ist, müssen Sie den Rückgabewert von putIfAbsent
verwenden, um zwischen
- der Eintrag noch vermisst wurde, zu unterscheiden (und der Standardwert ist aufgrund des Anruf hinzugefügt wurde), in diesem Fall das Verfahren kehrt
null
und
- ein anderer Thread ist, das Rennen und eingefügt, um den neuen Eintrag nach dem Aufruf von
get
(in diesem Fall das Verfahren gibt den aktuellen Wert, die mit dem gegebenen Schlüssel)
gewonnen
Sie abstrahieren kann diese Sequenz durch eine Hilfsmethode einzuführen, zum Beispiel
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;
}
}
}
Sie dies in Ihrem Beispiel verwenden:
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 ...
}
}
Beachten Sie, dass dies tatsächlich bereits im JDK 8 vorgesehen ist als default
Methode auf Map
, aber da Sie noch auf JDK 7 sind, müssen Sie Ihre eigenen rollen, wie hier gemacht.