Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/email/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将ConcurrentHashMap.merge()与共享的AtomicInteger一起使用_Java_Concurrency - Fatal编程技术网

Java 如何将ConcurrentHashMap.merge()与共享的AtomicInteger一起使用

Java 如何将ConcurrentHashMap.merge()与共享的AtomicInteger一起使用,java,concurrency,Java,Concurrency,我有一个共享的全局计数器,我想在执行并发计算并更新到映射之前检查它是否小于总数。如何使用现代java并发UTIL/API来确保这是原子的 类共享访问{ AtomicInteger globalCounter=新的AtomicInteger(); Map counterPerKey=新的ConcurrentHashMap() 阶级持有者{ 整数值 } 公共持有者递增ForkeyMultipleThreads(字符串键){ if(total.get()

我有一个共享的全局计数器,我想在执行并发计算并更新到映射之前检查它是否小于总数。如何使用现代java并发UTIL/API来确保这是原子的


类共享访问{
AtomicInteger globalCounter=新的AtomicInteger();
Map counterPerKey=新的ConcurrentHashMap()
阶级持有者{
整数值
}
公共持有者递增ForkeyMultipleThreads(字符串键){
if(total.get()<1000){
整数newTotal=counterPerKey.merge(key,1,Integer::sum);
globalCounter.increment();
返还新持有人(新总数);
}
}
}
编辑:合并函数实际上也是原子函数,这就解决了。因此,您可以通过多线程访问映射的其余部分,并在总计数器上使用atomic inc


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);

    }

  }

}

类共享访问{
AtomicInteger globalCounter=新的AtomicInteger();
Map counterPerKey=新的ConcurrentHashMap()
阶级持有者{
整数值
}
公共持有者递增ForkeyMultipleThreads(字符串键){
if(total.get()<1000){
整数newTotal=counterPerKey.merge(key,1,(v1,v2)->{
globalCounter.increment();
返回v1+v1;
}  
返还新持有人(新总数);
}
}
}

现代java仍然使用相同的线程安全基本原则。您有一个先检查后执行的场景,它几乎涵盖了整个方法。因此,您可以使方法
同步化

public synchronized Holder incrementForKeyMultipleThreads(String key) {
    if (globalCounter.get() < 1000) {
        globalCounter.increment();
        return new Holder(counterPerKey.merge(key, 1, Integer::sum));
    }
    return null;
}
public synchronized Holder incrementForKeyMultipleThreads(字符串键){
if(globalCounter.get()<1000){
globalCounter.increment();
返回新的持有者(counterkey.merge(key,1,Integer::sum));
}
返回null;
}

如果这是你唯一使用的地方(阅读或写作)
globalCounter
,您可以将其更改为
int

什么是
总计
?使用
同步
是对
原子整数
ConcurrentHashMap
@AbhijitSarkar使用的比较和设置的公然挑战。您可以分别对这两个原子进行更改,但如何更改这两个对象都在一个原子操作中?很想知道你是否发布了答案。回答这个问题的游戏有点晚了,但我发现合并函数在CHM中实际上是原子的。