有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是线程安全的只读枚举集迭代器吗?

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

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


共 (2) 个答案

  1. # 1 楼答案

    一个EnumSet内容可以改变,尽管对它的引用是最终的。没有EnumSet是不可变的。但是,您可以通过Collections.unmodifiableSet()包装EnumSet。如果还避免保留对原始EnumSet的任何引用,那么不可修改的包装器对象在功能上是不可变的

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

    无论如何,EnumSetcontains()方法可能不会创建或使用迭代器。该类通过位向量实现成员身份,因此它使用位操作来执行contains()测试

  2. # 2 楼答案

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

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

    请注意,如果您在一个线程中修改集合,同时在另一个线程中对其进行迭代(例如,通过contains),那么这一部分文档将发挥作用:

    The returned iterator is weakly consistent: it will never throw ConcurrentModificationException and it may or may not show the effects of any modifications to the set that occur while the iteration is in progress.