Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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中放置线程时,当前值的增量是否安全?_Java_Concurrenthashmap - Fatal编程技术网

Java 在ConcurrentHashMap中放置线程时,当前值的增量是否安全?

Java 在ConcurrentHashMap中放置线程时,当前值的增量是否安全?,java,concurrenthashmap,Java,Concurrenthashmap,我想知道在将当前值放入ConcurrentHashMap时修改它会发生什么 我有ConcurrentHashMap(ConncurentHashMap出席人数)以及会议厅名称和每个会议厅的访客人数的现有映射 每次调用visit(conferenceHallName)方法都会增加给定会议厅的访客数量。每个调用程序都是一个线程 因此,方法如下: public void visit(String conferenceHallName) { attendance.put(conferenc

我想知道在将当前值放入
ConcurrentHashMap
时修改它会发生什么

我有
ConcurrentHashMap
ConncurentHashMap出席人数
)以及会议厅名称和每个会议厅的访客人数的现有映射

每次调用
visit(conferenceHallName)
方法都会增加给定会议厅的访客数量。每个调用程序都是一个线程

因此,方法如下:

public void visit(String conferenceHallName) {    
   attendance.put(conferenceHallName, attendance.get(conferenceHallName) + 1);    
}
put()
是锁定方法,
get()
不是。但在这种情况下首先会发生什么:

  • 线程将用这个映射锁定段,然后计算一个新值,然后放置并释放它,这对我来说是完美的 或
  • 线程将获得旧值,计算一个新值,然后锁定段并放置,这意味着不一致性,我需要找到解决方法

  • 如果第二个场景是实际发生的情况,那么使用
    AtomicInteger
    而不是
    Integer
    是否可以解决我的问题?

    第二个描述更接近实际发生的情况:线程将以线程安全的方式访问值,使用更新的计数构造一个新的
    Integer
    ,然后锁定映射,并替换该对象

    使用
    AtomicInteger
    而不是
    Integer
    将解决以下问题:

    attendance.get(conferenceHallName).getAndIncrement();
    

    这是假设所有
    conferenceHallName
    键在映射中都已正确设置。

    如果您使用的是Java 8,则可以通过
    attention.merge(conferenceHallName,1,Integer::sum)获得正确的行为。