Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The previous compliant solution is safe for multithreaded use but does not scale because of excessive synchronization, which can lead to contention and deadlockdecreased performance.

Wiki Markup
The {{ConcurrentHashMap}} class used in this compliant solution provides several utility methods for performing atomic operations and is often a good choice for algorithms that must scale \[[Lee 2009|AA. References#Lee 09]\].

Note that this compliant solution still requires synchronization, because without it, the test to prevent overflow and the increment will not happen atomically, so two threads calling increment() can still cause overflow. The synchronization block is smaller, and does not include the lookup or addition of new values, so it has less of an impact on performance as the previous compliant solution.

Code Block
bgColor#ccccff
final class KeyedCounter {
  private final ConcurrentMap<String, AtomicInteger> map =
      new ConcurrentHashMap<String, AtomicInteger>();
  private final Object lock = new Object();

  public void increment(String key) {
    AtomicInteger value = new AtomicInteger();
    AtomicInteger old = map.putIfAbsent(key, value);

    if (old != null) {
      value = old;
    }


    }

    synchronized (lock) {
      if (value.get() == 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 == null) ? null : value.get();
  }

  // Other accessors ...
}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="8466bb244d4ba210-70c1f6fc-47174d38-81d6825e-a88bab24a9013d393c065a24"><ac:plain-text-body><![CDATA[

[[API 2006

AA. References#API 06]]

 

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="46e4abd3139d7d32-a6453491-4ed64f43-bdeda38c-b05a7aefb6aa80fd7d097afc"><ac:plain-text-body><![CDATA[

[[Goetz 2006

AA. References#Goetz 06]]

Section 4.4.1, Client-side Locking

]]></ac:plain-text-body></ac:structured-macro>

 

Section 5.2.1, ConcurrentHashMap

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="0bb3ae84f55379ae-1145c26d-475e4b16-981abaf0-f29ff24c2934d7692b5f3276"><ac:plain-text-body><![CDATA[

[[JavaThreads 2004

AA. References#JavaThreads 04]]

Section 8.2, Synchronization and Collection Classes

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="326ca6010c70624b-0b02537b-4872481b-8ea98bc7-c630f03ac9f299127e9271d0"><ac:plain-text-body><![CDATA[

[[Lee 2009

AA. References#Lee 09]]

Map & Compound Operation

]]></ac:plain-text-body></ac:structured-macro>

...