首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >java散列图线程可见性

java散列图线程可见性
EN

Stack Overflow用户
提问于 2011-03-02 22:44:23
回答 7查看 2.5K关注 0票数 9

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

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-03-02 22:46:55

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

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

编辑:最初,我完全忽略了map如何初始化的问题。在(再次)读取one of the Pugh articles之后,似乎映射确实需要是最终的,才能使初始化数据变得可见:

能够看到字段的正确构造的值是很好的,但是如果字段本身是一个引用,那么您还希望您的代码能够看到它所指向的对象(或数组)的最新值。如果您的字段是最终字段,这也是有保证的。因此,您可以有一个指向数组的最终指针,而不必担心其他线程看到数组引用的正确值,但看到数组内容的错误值。同样,这里所说的“正确”,我们指的是“对象构造函数结束时的最新值”,而不是“可用的最新值”。

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

票数 8
EN

Stack Overflow用户

发布于 2011-03-02 22:57:11

如果您将HashMap声明为final,并且预初始化一个本地HashMap,然后将全局HashMap与本地一起存储,则在构造函数初始化之后,HashMap的内容将变为可见。

必须正确使用

Final字段以提供不可变性的保证。当一个对象的构造函数完成时,它被认为是完全初始化的。只有在对象完全初始化后才能看到对该对象的引用的线程,一定会看到该对象的最终字段的正确初始化值。

http://www.cs.umd.edu/~pugh/java/memoryModel/jsr133.pdf

票数 4
EN

Stack Overflow用户

发布于 2011-03-02 22:47:06

从Guava使用ImmutableMap将是最好的解决方案。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5169101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档