java - 在多线程环境下使用 HashMap

标签 java multithreading

我正在做一个面试题 on JavaRevisited我很难理解这个问题:

What’s wrong with using a HashMap in a multithreaded environment? When get() method go into an infinite loop?

在我看来,使用HashMap 不是问题在多线程环境中,只要我们的应用程序没有访问/读取正在修改创建的 HashMap 的线程,而不是简单地访问 HashMap。

因此,在我看来,只要在应用程序中我们只是访问 HashMap 就没有问题。在多线程环境中。

请让我知道我的理解是否正确。

最佳答案

What’s wrong using HashMap in multithreaded environment? When get() method go to infinite loop?

让多个线程以不 protected 方式使用非同步集合(实际上是任何可变类)是一个错误。如果每个 线程都有自己的 HashMap 就确定了instance 那么这不是问题。如果多个线程正在添加到同一个,这是一个问题 HashMap没有它的实例 synchronized .即使只有 1 个线程正在修改 HashMap和其他线程在没有同步的情况下从同一张 map 读取,你会遇到问题。

如果您需要在多个线程中使用相同的哈希表对象,那么您应该考虑使用 ConcurrentHashMap ,包装对 HashMap 的每个访问在synchronized {} block ,或利用 Collections.synchronizedMap(new HashMap<...>())构造。

很有可能 get()进入无限循环,因为其中一个线程只有 HashMap部分更新 View 。在内存中,并且必须有某种对象引用循环。这就是使用具有多个线程的非同步集合的危险。

So in my understanding, it's not a problem as long as in the application we are just accessing the HashMap in a multi-threaded environment?

如果“访问”是指“阅读”,那么有资格就是这样。您必须确保:

  • HashMap 的所有更新线程被实例化之前完成并且创建映射的线程也 fork 线程
  • 线程仅使用 HashMap在只读模式下 – get()或不删除的迭代
  • 没有线程更新 map

如果这些条件中的任何一个不成立,那么您将需要改用同步 map 。

关于java - 在多线程环境下使用 HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11050539/

相关文章:

.net - 并行 Foreach 内存问题

Python 从预定事件返回值

java - 如何在Listview中设置Retrofit响应正文数据

java - 如何覆盖资源包属性

java - 为什么 ConcurrentSkipListSet 升序迭代器 'faster' 而不是降序迭代器?

Java:线程安全的 RandomAccessFile

c++ - 在线程退出时重生线程

multithreading - POSIX线程参数

java - 创建名称为 'flywayInitializer' 的 bean 时出错

java - libsdl 类消耗所有 JVM(阻止代码的执行)