在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所有更新,并且创建映射的线程也会分叉线程
  • 线程仅以只读模式使用HashMapget()或迭代)
  • 没有线程更新地图

如果这些条件中的任何一个不正确,那么您将需要使用同步映射。

这是一个经典问题。 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