title: How to utilize ConcurrentHashMap.merge() with a shared AtomicInteger
body: <p>I have a shared global counter that I want to check is less than a total before doing a concurrent computation and update into a map. How can I use modern java concurrency utils / API to ensure this is atomic?</p>
  
  <pre class="lang-java prettyprint-override"><code>
  class SharedAccess {
  
      AtomicInteger globalCounter = new AtomicInterger();
      Map&lt;String, Integer&gt; counterPerKey = new ConcurrentHashMap&lt;&gt;()
  
      class Holder{
          Integer value
      }
  
      public Holder incrementForKeyMultipleThreads(String key) {
           if (total.get() &lt; 1000) {
  
            Integer newTotal = counterPerKey.merge(key, 1, Integer::sum);
            globalCounter.increment();
           return new Holder(newTotal);
  
      }
  
    }
  
  }
  
  </code></pre>
  
  <p>EDIT: This is solved by the merge function actually being atomic too. Therefore you get the benefit of the multiple thread access to the rest of the map, and the atomic inc on the total counter. </p>
  
  <pre><code>
  class SharedAccess {
  
      AtomicInteger globalCounter = new AtomicInterger();
      Map&lt;String, Integer&gt; counterPerKey = new ConcurrentHashMap&lt;&gt;()
  
      class Holder{
          Integer value
      }
  
      public Holder incrementForKeyMultipleThreads(String key) {
           if (total.get() &lt; 1000) {
  
            Integer newTotal = counterPerKey.merge(key, 1, (v1, v2) -&gt; {
                globalCounter.increment();
                return v1+v1;
            }  
  
           return new Holder(newTotal);
  
      }
  
    }
  
  }
  </code></pre>