当两个线程试图在并发hashmap中放入相同的键值时会发生什么

use*_*869 2 java multithreading

想象一下,有两个线程A,B将分别在地图中放置两个不同的值,即v1和v2,具有相同的密钥.密钥最初不存在于映射中线程A调用containsKey并发现密钥不存在,但是立即挂起线程B调用containsKey并发现密钥不存在,并且有时间插入其值v2

当线程A回来时,会发生什么?我假设,它调用put方法反过来调用putIfAbsent但是密钥已经存在于线程B.so线程A将不会覆盖该值

但是从这个链接我发现线程A恢复并插入v1,"和平"覆盖(因为put是线程安全的)线程B插入的值 是ConcurrentHashMap完全安全吗?

Sol*_*low 5

以下是ConcurrentHashMap将为您做的事情:

(1)键/值对不会神秘地出现在地图中.如果您尝试获取某个键的值,则可以保证获得程序中某个线程与该键一起存储的值,或者如果没有线程存储过该键的值,您将获得空引用.

(2)键/值对不会神秘地从地图上消失.如果你为之前有一个值的某个K调用get(K),并且返回null引用,那是因为程序中的某个线程存储了null.

(3)它不会使程序死锁或挂起或崩溃.

以下是ConcurrentHashMap 不会为您做的事情:

它不会使您的程序"线程安全".

关于线程安全最重要的事情是:完全从"线程安全"组件构建模块或程序不会使程序或模块"线程安全".你的问题是一个很好的例子.

ConcurrentHashMap是一个线程安全的对象.无论有多少线程同时访问它,它将保留我在上面列出的promise(1),(2)和(3).但是如果你的两个程序的每个线程都尝试同时为同一个键的地图放置一个不同的值,那就是数据竞争.当其他一些线程稍后查找该键时,它获得的值将取决于哪个线程赢得了比赛.

如果程序的正确性取决于哪个线程赢得数据竞争,那么即使构建它的对象称为"线程安全",程序也不是"线程安全的".