2

我有一个EnumSet最终的和不可变的,即在构造函数中初始化一次。

contains()这个EnumSet线程上的方法安全吗?它在内部使用迭代器进行包含检查。因此,如果两个线程同时调用contains()一个调用中的迭代器位置是否会影响另一个?还是迭代器在这两个线程调用中具有不同的实例?

4

2 回答 2

1

尽管对它的引用是最终的,但它的内容EnumSet可以更改。否是不可变的。但是,您可以包装您的via 。如果您还避免保留对原始对象的任何引用,则不可修改的包装对象在功能上是不可变的。EnumSetEnumSetCollections.unmodifiableSet()EnumSet

Set尽管存在可变性,但只要Set不修改,两个迭代器同时操作相同就不会出现问题。这与只有一个迭代器的情况并没有什么不同。

在任何情况下,可能的contains()方法EnumSet都不会创建或使用迭代器。该类通过位向量实现成员资格,因此它使用位操作来执行contains()测试。

于 2014-10-16T17:08:09.547 回答
0

不,如果两个线程contains()同时调用,那将调用iterator()两次,这将创建两个单独的迭代器。

如果您试图在两个线程之间共享一个迭代器,不是一个好主意。

请注意,如果您在一个线程中修改集合,同时在另一个线程中迭代它(例如 via contains),那么文档的这一点就会发挥作用:

返回的迭代器是弱一致的:它永远不会抛出 ConcurrentModificationException 并且它可能会或可能不会显示迭代正在进行时对集合进行的任何修改的影响。

于 2014-10-16T16:59:44.030 回答