当两个线程试图将相同的键值放入并发 hashmap 时会发生什么 [英] What happens when two threads trying to put the same key value in concurrent hashmap

查看:49
本文介绍了当两个线程试图将相同的键值放入并发 hashmap 时会发生什么的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设有两个线程 A、B 将在映射中放置两个不同的值,分别为 v1 和 v2,具有相同的键.密钥最初不存在于地图中线程A调用containsKey,发现key不存在,立即挂起线程B调用containsKey,发现key不存在,有时间插入其值v2

当线程 A 返回时,会发生什么?.我假设,它调用 put 方法,然后调用 putIfAbsent但是键已经被线程 B 插入了,所以线程 A 不会覆盖这个值

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

解决方案

ConcurrentHashMap 将为您做的事情:

(1) 键/值对不会神秘地出现在映射中.如果您尝试获取某个键的值,您肯定会获得程序中某个线程使用该键存储的值,或者如果没有线程曾经存储过该键的值,您将获得一个空引用.

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

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

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

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

关于线程安全要记住的最重要的一点是:完全从线程安全"组件构建模块或程序将不会使程序或模块成为线程安全".你的问题是为什么不这样做的完美例子.

ConcurrentHashMap 是一个线程安全的对象.无论有多少线程同时访问它,它都会遵守我上面列出的承诺(1)、(2)和(3).但是,如果您程序的两个线程都尝试同时将不同的值放入映射中的同一个键,那就是数据竞争.当其他线程稍后查找该键时,它获得的值将取决于哪个线程赢得了比赛.

如果您的程序的正确性取决于哪个线程在数据竞争中获胜,那么您的程序就不是线程安全的",即使构建它的对象被称为线程安全的".

Imagine there are two threads A, B that are going to put two different values in the map, v1 and v2 respectively, having the same key. The key is initially not present in the map Thread A calls containsKey and finds out that the key is not present, but is immediately suspended Thread B calls containsKey and finds out that the key is not present, and has the time to insert its value v2

When thread A is back,what happens?. I assume that,It calls put method which in turn calls putIfAbsent But the key is already there inserted by thread B.so thread A will not override the value

But from this link i found that Thread A resumes and inserts v1, "peacefully" overwriting (since put is threadsafe) the value inserted by thread B Is ConcurrentHashMap totally safe?

解决方案

Here's what ConcurrentHashMap will do for you:

(1) Key/value pairs won't mysteriously appear in the map. If you try to get a value for some key, You are guaranteed to get a value that some thread in your program stored with that key, or you will get a null reference if no thread has ever stored a value for that key.

(2) key/value pairs won't mysteriously disappear from the map. If you call get(K) for some K that previously had a value, and a null reference comes back, it's because some thread in your program stored the null.

(3) It won't deadlock or hang or crash your program.

Here's what ConcurrentHashMap will not do for you:

It won't make your program "thread safe".

The most important thing to remember about thread safety is this: Building a module or a program entirely from "thread-safe" components will not make the the program or module "thread-safe". Your question is a perfect example of why not.

ConcurrentHashMap is a thread-safe object. No matter how many threads access it at the same time, it will keep the promises (1), (2), and (3) that I listed above. But if two of your program's threads each try put a different value into the map for the same key at the same time, that's a data race. When some other thread later looks up that key, the value that it gets will depend on which thread won the race.

If the correctness of your program depends on which thread wins a data race, then your program is not "thread-safe" even though the objects from which it was built are called "thread safe".

这篇关于当两个线程试图将相同的键值放入并发 hashmap 时会发生什么的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆