Java Enum值子集线程安全性

时间:2012-07-09 18:39:22

标签: java enums thread-safety

  

可能重复:
  How thread-safe is enum in java?

enum类像

一样
public enum Type
{
    ONE, TWO, THREE, FOUR
}

Type.values()数组线程是否可以安全地在for循环中访问,例如,在静态方法中?例如:

public static void process()
{
    for (Type type:Type.values())
    {
        // Do something
    }
}

此外,如果使用这些值的任何子集定义静态数组变量,那么读取的线程安全吗?例如:

public static final Type[] TYPES = new Type[] {TWO, THREE};

public static void process()
{
    for (Type type:TYPES)
    {
        // Do something
    }
}

在这两种情况下,process()方法可能属于与Type enumtypes数组的定义不同的类。

此外,TYPES数组可以在Type enum中定义一次,并由enum的静态方法返回。

所以,鉴于上述情况,如果多个线程同时运行process()方法,代码是否是线程安全的(至少只是读取TYPES数组的值)?

3 个答案:

答案 0 :(得分:3)

方法Type.values()每次都返回一个新数组。这样做是因为数组是可变的,并且每次都必须返回一个新的副本以保证线程安全。

答案 1 :(得分:1)

枚举是保证线程安全的,它们是不可变的。因此,线程无法修改枚举的状态。

第二种情况,当你定义为final时,它也是线程安全的,你不能修改错误的引用。

请记住,您不能仅更改“引用”,但可以更改数组的状态。

答案 2 :(得分:1)

其他人已经指出values()方法returns a new array each time,所以它是线程安全的。

然而,要回答你的第二个问题:

  

如果使用这些值的任何子集定义静态数组变量,那么它是否是线程安全的?

没有。 任何 public static数组都不安全,因为数组元素总是可变的。 也就是说,任何线程都可以将TYPES[0]更改为任何其他Type,这在存在多个线程时是不安全的 - 或者甚至在单线程程序中也是如此。

更好的方法是公开List<Type>,然后可以安全地使其成为不可变的(例如,使用Collections.unmodifiableList())。