对于不同的密钥,HashMap是线程安全的吗? [英] Is a HashMap thread-safe for different keys?
问题描述
如果我有两个多线程访问HashMap,但保证它们永远不会同时访问同一个键,那么这是否仍然会导致竞争状态?
他是正确的。如果线程正在使用不相交的密钥集,那么未经同步更新的HashMap将会破解偶。
-
如果一个线程执行
code>,那么另一个线程可能会看到散列表大小的陈旧值。放置
-
当线程执行
时, / code>会触发表的重建,另一个线程可能会看到散列表数组引用的瞬态或过时版本,其大小,其内容或散列链。混沌可能随之而来。
-
当一个线程为一个与某些使用的键冲突的键执行
放置
通过其他线程,而后者线程为它的键执行put
,那么后者可能会看到散列链参考的陈旧副本。当一个线程用一个与某个其他线程的键冲突的键来检测该表时,它可能会遇到该链上的该键。 它会调用该键上的equals,并且如果线程未同步,则equals方法可能会在该键中遇到陈旧状态。
如果您有两个线程同时执行放置
或删除
请求,则竞争条件有很多机会。
我可以想到三个解决方案:
- 使用
ConcurrentHashMap
。 - 使用常规
HashMap
,但在外部同步;例如使用原始互斥体,Lock
对象等等。 - 使用不同的
HashMap
为每个线程。如果线程真的有一组不相交的键,那么应该没有必要(从算法的角度来看)他们共享一个Map。事实上,如果你的算法涉及线程迭代关键字,值或某些地点的地图条目,将单个地图拆分为多个地图可以为处理的这一部分提供显着的加速。
If I have two multiple threads accessing a HashMap, but guarantee that they'll never be accessing the same key at the same time, could that still lead to a race condition?
In @dotsid's answer he says this:
If you change a HashMap in any way then your code is simply broken.
He is correct. A HashMap that is updated without synchronization will break even if the threads are using disjoint sets of keys. Here are some of the things that can go wrong.
If one thread does a
put
, then another thread may see a stale value for the hashmap's size.When a thread does a
put
that triggers a rebuild of the table, another thread may see transient or stale versions of the hashtable array reference, its size, its contents or the hash chains. Chaos may ensue.When a thread does a
put
for a key that collides with some key used by some other thread, and the latter thread does aput
for its key, then the latter might see a stale copy of hash chain reference. Chaos may ensue.When one thread probes the table with a key that collides with one of some other thread's keys, it may encounter that key on the chain. It will call equals on that key, and if the threads are not synchronized, the equals method may encounter stale state in that key.
And if you have two threads simultaneously doing put
or remove
requests, there are numerous opportunities for race conditions.
I can think of three solutions:
- Use a
ConcurrentHashMap
. - Use a regular
HashMap
but synchronize on the outside; e.g. using primitive mutexes,Lock
objects, etcetera. - Use a different
HashMap
for each thread. If the threads really have a disjoint set of keys, then there should be no need (from an algorithmic perspective) for them to share a single Map. Indeed, if your algorithms involve the threads iterating the keys, values or entries of the map at some point, splitting the single map into multiple maps could give a significant speedup for that part of the processing.
这篇关于对于不同的密钥,HashMap是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!