java HashMap 线程可见性

标签 java multithreading concurrency

我在初始化时完全加载了一个 java HashMap,但是在初始化之后多个线程将从 HashMap 读取数据。我想避免任何类型的同步,因为 map 本质上是只读的并且永远不会改变。但是我能保证所有键和值对所有线程都是可见的吗?

最佳答案

如果 map 的内容永远不会改变,那么您就没有问题。只有当变量的内容发生变化时,内存模型可见性问题才会发挥作用。

您可能希望同步 map 的初始化,以确保在完全初始化之前没有线程访问它,并确保加载到 map 中的值都是可见的。

编辑:最初我完全忽略了 map 如何初始化的问题。看完one of the Pugh articles (再次)似乎 map 确实需要最终才能使初始化数据可见:

The ability to see the correctly constructed value for the field is nice, but if the field itself is a reference, then you also want your code to see the up to date values for the object (or array) to which it points. If your field is a final field, this is also guaranteed. So, you can have a final pointer to an array and not have to worry about other threads seeing the correct values for the array reference, but incorrect values for the contents of the array. Again, by "correct" here, we mean "up to date as of the end of the object's constructor", not "the latest value available".

在 Java 规范中给出了强制“先发生”关系的条件列表,我应该在这里引用它们(或者如果其他人在他们的回答中这样做,我会投票赞成)。静态变量和 Holder 习惯用法当然是一种方法。这个问题非常广泛,因为它没有指定 map 的初始化方式,如果您发布一个描述您建议如何进行初始化的问题,您可能会得到更直接有用的答案。

关于java HashMap 线程可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5169101/

相关文章:

go - 如果写入从不在设计上相互竞争,那么使用 sync.RWMutex 的读取锁进行写入并使用其写入锁进行读取是否安全?

concurrency - 在erlang中测量并发循环时间

java - 如何使用JCheckBoxes selection for use?

java - 这与线程和阻塞队列有关吗?

java - 如何避免每个线程创建不同的池?

c - 无法理解或修复程序中的竞争条件

Java - 非最终领域的同步

没有 Eclipse 的 Java Web 开发

Java:有关中断的编译错误

java - 以原始文件名下载文件