对于不同的密钥,HashMap是线程安全的吗? [英] Is a HashMap thread-safe for different keys?

查看:125
本文介绍了对于不同的密钥,HashMap是线程安全的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有两个多线程访问HashMap,但保证它们永远不会同时访问同一个键,那么这是否仍然会导致竞争状态?


他是正确的。如果线程正在使用不相交的密钥集,那么未经同步更新的HashMap将会破解




  • 如果一个线程执行放置

    code>,那么另一个线程可能会看到散列表大小的陈旧值。
  • 当线程执行时, / code>会触发表的重建,另一个线程可能会看到散列表数组引用的瞬态或过时版本,其大小,其内容或散列链。混沌可能随之而来。


  • 当一个线程为一个与某些使用的键冲突的键执行放置通过其他线程,而后者线程为它的键执行 put ,那么后者可能会看到散列链​​参考的陈旧副本。当一个线程用一个与某个其他线程的键冲突的键来检测该表时,它可能会遇到该链上的该键。

  • 它会调用该键上的equals,并且如果线程未同步,则equals方法可能会在该键中遇到陈旧状态。




如果您有两个线程同时执行放置删除请求,则竞争条件有很多机会。

我可以想到三个解决方案:


  1. 使用 ConcurrentHashMap

  2. 使用常规 HashMap ,但在外部同步;例如使用原始互斥体, Lock 对象等等。

  3. 使用不同的 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 a put 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:

  1. Use a ConcurrentHashMap.
  2. Use a regular HashMap but synchronize on the outside; e.g. using primitive mutexes, Lock objects, etcetera.
  3. 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屋!

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