HashSet和多线程

时间:2017-02-18 09:55:05

标签: java multithreading collections concurrency java-7

我在Java 7上工作。

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

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

当我阅读Javadoc时,对我来说还不清楚。

HashSet Javadoc我们可以阅读

  

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

...

  

请注意,此实施未同步。

HashMap Javadoc上,我们可以阅读:

  

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

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

因此对方法contains的多次调用是否是线程安全的?

如果它是真的:JVM的所有实现(如IBM JVM)都能保证吗?

1 个答案:

答案 0 :(得分:4)

通常,在读取操作之间不会出现并发竞争(因而冲突)。读写操作之间出现并发问题。因此,交错的多个读取操作始终是线程安全的(如果我们假设这样一个线程安全的概念已经明确定义)。

现在,还有一种情况可能存在并发问题,这是在数据结构初始化期间,因为在您的情况下,这可以被认为是唯一的修改(写操作)。为了确保所有后续的contains()调用都能看到完全初始化的Set,您必须确保它已正确初始化。这个概念在Java中定义为“安全发布”,你可以阅读更多关于它here或书籍"Java Concurrency in Practice"的书。

总而言之,Collections.unmodifiableSet()通过final字段以安全的方式发布结果。 所以,是的,您确定所有contains()都会看到完全初始化Set