Java 修改ConcurrentHashMap中的值

Java 修改ConcurrentHashMap中的值,java,java.util.concurrent,concurrenthashmap,Java,Java.util.concurrent,Concurrenthashmap,在ConcurrentHashMap中有分段的概念。这意味着,如果两个线程试图访问ConcurrentHashMap,它们会将其分成两个块,默认块大小为16 现在假设ConcurrentHashMap只有两个元素,两个不同的线程出现,thread1尝试修改第一个值,thread2尝试修改第二个值。在这种情况下,ConcurrentHashMap是否将用于分段 现在,在不同的场景中,两个线程尝试修改相同的值ConcurrentHashMap将如何处理这种情况?通过使用锁定机制还是有其他原因 CHM

在ConcurrentHashMap中有分段的概念。这意味着,如果两个线程试图访问ConcurrentHashMap,它们会将其分成两个块,默认块大小为16

现在假设ConcurrentHashMap只有两个元素,两个不同的线程出现,thread1尝试修改第一个值,thread2尝试修改第二个值。在这种情况下,ConcurrentHashMap是否将用于分段


现在,在不同的场景中,两个线程尝试修改相同的值ConcurrentHashMap将如何处理这种情况?通过使用锁定机制还是有其他原因

CHM保证这些操作(例如,
put
putIfAbsent
等)不会重叠,是的,这是通过锁定完成的。CHM的每个段都有自己的锁,每当您修改该段时都会使用该锁


(作为参考,正如@Affe所指出的,如果您正在修改
ConcurrentHashMap
中某个值的内容,CHM不能做任何事情来确保线程安全。)

ConcurrentHashMap有几个bucket。密钥根据其哈希值映射到其中一个存储桶中。添加或检索值时,与该键关联的存储桶将被锁定

在第一个问题中,有两种可能性:要么两个键位于同一个桶中,要么它们位于不同的桶中。在第一种情况下,一次只能有一个线程工作——第一个获得锁的线程将抓住它并工作,第二个线程将等待轮到它。在第二种情况下,当密钥位于不同的存储桶中时,它们将分别获得独立的锁并同时执行其工作


对于你的第二个问题,是桶被锁定了,而不是别的。如果两个线程尝试为同一个键存储两个值,那么ConcurrentHashMap承诺两个值中的一个将与该键关联。i、 e.如果线程A运行
map.put(“Answers”,2)和线程B运行
map.put(“Answers”,10)
,然后ConcurrentHashMap将确保map是有效的,并且包含
2
10
“Answers”
,但它不会对这两个选项中的哪一个做出任何承诺。

首先,CHM的新实现根本不使用分段,它仍然使用节点数组,如果给定索引中的节点不存在,并且两个线程试图插入两个哈希代码等于给定索引的条目,则CHM使用CAS;否则,如果节点存在,则CHM使用此节点的第一个元素上的锁来输入新值。CHM中的读取是非阻塞的,在不安全类的原子读取的帮助下,在保证之前使用。查看我关于CHM的博客了解更多详细信息

您需要定义“修改值”。hashmap完全不关心更改其值的属性,并且根本不与之交互,请显示示例代码;如果两个线程试图更改同一个键的值,则引用的所有赋值都是这样;默认情况下,这将是原子的权利?那么,在这种情况下,我们为什么需要CHM或Lock呢?因为
put
不仅仅是简单的赋值:它可能需要分配空间,并保留一个计数器来记录它有多少个条目。看看代码(旧链接,但仍然相关):PlusOne!非常感谢。知道了。