Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Sorry David, as discussed today we are getting rid of the int overflow checks so I need to revert to the old version.

...

Code Block
bgColor#FFCCCC
final class KeyedCounter {
  private final Map<String, Integer> map =
    Collections.synchronizedMap(new HashMap<String, Integer>(); 
  private final Object lock = new Object();

  public void increment(String key) {
    synchronized (lock) {
      Integer old = map.get(key);
      int oldValuevalue = (old == null) ? 01 : old.intValue() + 1;
    if (oldValue == Integer.MAX_VALUE) { map.put(key, value);
    }
  }

  public Integer getCount(String key) {
 throw new ArithmeticException("Out ofsynchronized range");(lock) {
    }
   return map.putget( key, value + 1);
  }

  public Integer getCount(String key) {}
    return map.get(key);
  }
}
}

Note that while this code is thread-unsafe, it at least prevents integer overflow when incrementing the map values, as mandated by INT00-J. Perform explicit range checking to ensure integer operations do not overflow.

...

Code Block
bgColor#ccccff
final class KeyedCounter {
  private final Map<StringConcurrentMap<String, Integer>AtomicInteger> map = new HashMap<String, Integer>(); 
  private final Objectnew lock = new ObjectConcurrentHashMap<String, AtomicInteger>();

  public void increment(String key) {
    synchronized (lock) {AtomicInteger value = new AtomicInteger(0);
    AtomicInteger  Integer old = map.getputIfAbsent(key, value);
   
   int oldValue =if (old =!= null) ? 0 : old.intValue(); { 
      value = old; 
    }

  if (oldValue == Integer.MAX_VALUE) {    
        throw new ArithmeticException("Out of range" value.incrementAndGet(); // Increment the value atomically
  }

  public Integer getCount(String key) {
    AtomicInteger value = map.get(key);
      }return value.get();
      map.put( key, value + 1);
    }
  }

  public Integer getCount(String key) {
    synchronized (lock) {
      return map.get(key);
    }
  }
}
}

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.

The integer overflow check that should be used before incrementing has been omitted for brevity. To prevent overflow, 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 informationThis 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.

Compliant Solution (ConcurrentHashMap)

...