在multithreading环境中使用HashMap
我正在接受关于JavaRevisited的采访问题
我很难理解这个问题:
在multithreading环境中使用HashMap有什么问题? 当get()方法进入无限循环时?
根据我的观点,在multithreading环境中使用HashMap
不是问题,只要我们的应用程序不访问/读取正在修改创建的HashMap
线程,而不是简单地访问HashMap
所以在我的理解中,只要在应用程序中我们只是在multithreading环境中访问HashMap
,它就不是问题了?
如果我的理解是正确的,请告诉我。
在multithreading环境中使用HashMap有什么问题? 当get()方法进入无限循环?
有什么不对的是让多个线程以不受保护的方式使用非同步集合(实际上是任何类)。 确定如果每个线程都有自己的HashMap
实例,那么这不是问题。 例如,如果多个线程在没有synchronized
情况下添加到同一个 HashMap
实例,则会出现问题。 即使只有一个线程正在修改HashMap
而其他线程正在从同一个映射中读取而没有同步,您将遇到问题。
如果你需要在多个线程中使用相同的哈希表对象,那么你应该考虑使用ConcurrentHashMap
,在synchronized {}
块中包含对HashMap
每个访问,或者使用Collections.synchronizedMap(new HashMap<...>())
构造。
get()
进入无限循环,因为其中一个线程在内存中只有部分更新的HashMap
视图,并且必须有某种指针循环。 这是使用具有多个线程的非同步集合的危险。
所以在我的理解中,只要在应用程序中我们只是在multithreading环境中访问HashMap,它就不是问题了?
如果通过“访问”你的意思是“阅读”,那么资格certificate也是如此。 你必须确保:
- 在线程实例化之前完成对
HashMap
所有更新,并且创建映射的线程也会分叉线程 - 线程仅以只读模式使用
HashMap
(get()
或迭代) - 没有线程更新地图
如果这些条件中的任何一个不正确,那么您将需要使用同步映射。
这是一个经典问题。 ArrayList和HashMap不同步,而Vector和HashTable是。 因此,除非您自己非常谨慎地定义互斥锁,否则应该使用HashTable。
换句话说,例如HashTable中的方法将确保在任何给定时间没有其他线程正在使用HashTable。 如果使用HashMap,则必须通过确保在调用方法之前在HashMap上进行同步来手动执行此操作。
更新:checkout @ Gray的评论。 看起来用Collections.synchronizedMap(新的HashMap())包装HashMap是现在的方法。
编辑:其他海报的回答方式比我做得好。 然而,我的回答引起了关于即将被弃用的Vector,Stack,Hashtable和Dictionary类的使用的有趣讨论,所以我在这里留下问题,作为下面评论的头。 多谢你们!
这里给出了详细的解释http://javabypatel.blogspot.in/2016/01/infinite-loop-in-hashmap.html
我猜他们打算访问HashMap
的共享副本。 Shared mutable state
。
由于它没有synchronized
每个线程都会从主内存中获取副本,修改并覆盖它。
HashMap with one entry thread 1 grab the copy thread 2 grab the copy thread 1 modify thread 2 modify thread 1 is done, and stores the copy in the main memory now memory is thread 2 is done and stores the copy now memory is The state thread 1 is lost