简体   繁体   中英

How to utilize ConcurrentHashMap.merge() with a shared AtomicInteger

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?


class SharedAccess {

    AtomicInteger globalCounter = new AtomicInterger();
    Map<String, Integer> counterPerKey = new ConcurrentHashMap<>()

    class Holder{
        Integer value
    }

    public Holder incrementForKeyMultipleThreads(String key) {
         if (total.get() < 1000) {

          Integer newTotal = counterPerKey.merge(key, 1, Integer::sum);
          globalCounter.increment();
         return new Holder(newTotal);

    }

  }

}

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.


class SharedAccess {

    AtomicInteger globalCounter = new AtomicInterger();
    Map<String, Integer> counterPerKey = new ConcurrentHashMap<>()

    class Holder{
        Integer value
    }

    public Holder incrementForKeyMultipleThreads(String key) {
         if (total.get() < 1000) {

          Integer newTotal = counterPerKey.merge(key, 1, (v1, v2) -> {
              globalCounter.increment();
              return v1+v1;
          }  

         return new Holder(newTotal);

    }

  }

}

Modern java still uses the same basic principles of thread-safety. You have a check-then-act scenario, which covers pretty much the whole method. So you can make the method synchronized :

public synchronized Holder incrementForKeyMultipleThreads(String key) {
    if (globalCounter.get() < 1000) {
        globalCounter.increment();
        return new Holder(counterPerKey.merge(key, 1, Integer::sum));
    }
    return null;
}

And then if this is the only place you are using (reading or writing) globalCounter , you can change it to int .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM