...
Code Block |
---|
|
final class KeyedCounter {
private final Map<String, Integer> map = new HashMap<String, Integer>();
private final Object lock = new Object();
public void increment(String key) {
synchronized (lock) {
Integer old = map.get(key);
int value = (old == null) ? 1 : old.intValue() + 1;
map.put(key, value);
}
}
public Integer getCount(String key) {
synchronized (lock) {
return map.get(key);
}
}
// Other accessors ...
}
|
Because the check for integer overflow following the addition is absent, the caller must ensure that the increment()
method is called no more than Integer.MAX_VALUE
times for any key. Refer to INT00-J. Perform explicit range checking to ensure integer operations do not overflow for more information.
...
Code Block |
---|
|
final class KeyedCounter {
private final ConcurrentMap<String, AtomicInteger> map =
new ConcurrentHashMap<String, AtomicInteger>();
public void increment(String key) {
AtomicInteger value = new AtomicInteger(0);
AtomicInteger old = map.putIfAbsent(key, value);
if (old != null) {
value = old;
}
value.incrementAndGet(); // Increment the value atomically
}
public Integer getCount(String key) {
AtomicInteger value = map.get(key);
return value.get();
}
// Other accessors ...
}
|
This compliant solution does not use Collections.synchronizedMap()
because locking on the (unsynchronized) map provides sufficient thread-safety for this application. The guideline CON40-J. Do not synchronize on a collection view if the backing collection is accessible provides more information about synchronizing on synchronizedMap
objects.
...
Code Block |
---|
|
final class KeyedCounter {
private final ConcurrentMap<String, AtomicInteger> map =
new ConcurrentHashMap<String, AtomicInteger>();
public void increment(String key) {
AtomicInteger value = new AtomicInteger();
AtomicInteger old = map.putIfAbsent(key, value);
if (old != null) {
value = old;
}
value.incrementAndGet(); // Increment the value atomically
}
public Integer getCount(String key) {
AtomicInteger value = map.get(key);
return value.get();
}
// Other accessors ...
}
|
Wiki Markup |
---|
According to Goetz et al. \[[Goetz 06|AA. Java References#Goetz 06]\] section 5.2.1. ConcurrentHashMap: |
...