当前位置: 首页 > 知识库问答 >
问题:

哈希集和多线程

景品
2023-03-14

我在Java 7号工作。

我想知道contains方法在HashSet对象上是否是线程安全的。

散列集由一个线程初始化。然后我们用不可修改的集合(collections.unmodifiableSet)包装HashSet。初始化后,多个线程只调用contains方法。

当我阅读Javadoc时,它对我来说是不清楚的。

在HashSet Javadoc上,我们可以阅读

这个类实现Set接口,由一个哈希表(实际上是一个HashMap实例)支持。

...

请注意,此实现不是同步的。

在HashMap Javadoc上,我们可以看到:

请注意,此实现不是同步的。如果多个线程并发访问一个哈希映射,并且其中至少一个线程在结构上修改了该映射,则必须在外部对其进行同步。(结构化修改是添加或删除一个或多个映射的任何操作;仅仅更改与实例已包含的键关联的值不是结构化修改。)

对我来说,这意味着contains方法不是结构修改。

因此对方法的多次调用包含它是线程安全的吗?

如果它是真的:它是否在JVM的所有实现(比如IBM JVM)上得到保证?

共有1个答案

袁何平
2023-03-14

一般而言,只读操作之间不可能存在并发竞争(因此也不可能存在冲突)。读和写操作之间会出现并发问题。因此,交错的多个读操作总是线程安全的(如果我们假设线程安全的概念定义良好的话)。

现在,还有一种情况可能会出现并发问题,这是在初始化数据结构的过程中,因为在您的情况下,这可以被认为是唯一的修改(写操作)。为了确保所有后续的contains()调用都将看到完全初始化的集合,您必须确保它已正确初始化。这个概念在Java被定义为“安全发布”,您可以在这里或在“Java并发实践”一书中阅读更多有关它的内容。

最后,collections.unmodifiableSet()通过final字段以安全的方式发布结果。因此,是的,您可以确保所有contains()将看到完全初始化的

 类似资料:
  • Swift 4集合是用于存储相同类型的不同值,但它们没有像数组那样的有明确排序顺序。 如果不需要元素排序,或者需要没有重复值(唯一值),则可以使用集合而不是数组(集合只允许不同的值)。 类型必须是可散列类型并且是可以比较的,才能存储在一个集合中。哈希值是对象的值相等。例如,如果两个对象相等:,则。 默认情况下,所有基本值都是可散列类型,可以用作集合值。 创建集 使用以下初始化语法创建某个类型的空集

  • 在许多Redis教程中(比如本教程),数据存储在一个集合中,但多个值组合在一个字符串中(即,用户帐户可以作为两个条目“user:1000:username”和“user:1000:password”存储在集合中)。 然而,Redis也有哈希。似乎拥有一个“user:1000”散列会更有意义,它包含一个“username”条目和一个“password”条目。您只需直接在哈希中访问它们,而不是连接字符

  • 问题内容: 我正在编写一个将HashMap返回给用户的应用程序。用户将获得对此MAP的引用。在后端,我将运行一些线程来更新Map。 到目前为止我做了什么? 我已经使所有后端线程都共享一个公用通道来更新MAP。因此,在后端,我确信并发写入操作不会成为问题。 我遇到的问题 如果用户尝试更新MAP并同时在后端更新MAP->并发写入操作问题。 如果使用尝试从MAP读取某些内容,同时MAP正在后端更新->并

  • 我正在用一个字符串数组单维和一个2维int数组制作哈希表。我正在使用线性探测进行冲突检测,当我意识到如果检测到冲突,单词的hashCode将不再是索引时,我真的很兴奋地完成了这个程序。我该如何保存该索引以备以后使用?

  • 嗨,我想知道如果你有你要寻找的对象的Hashcode,是否可以直接访问HashSet的内容,有点像在HashMap中使用Hashcode作为键。 我想它可能会像这样工作: 谢谢 编辑:谢谢你的回答。好的,我知道我可能会稍微推动HashSet的契约,但是对于这个特定的项目,等式完全由hashcode决定,我确信每个hashcode/hashbucket只有一个对象。我非常不愿意使用HashMap的原

  • 1. HashMap概述 HashMap是基于哈希表的Map接口的非同步实现(Hashtable跟HashMap很像,唯一的区别是Hashtalbe中的方法是线程安全的,也就是同步的)。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。 2. 四个关注点在HashMap上的答案 关注点 结论 HashMap是否允许空 Key和Val