0

重複の可能性:
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配列の値を読み取るためだけに)?

4

3 に答える 3

3

このメソッドType.values()は毎回新しい配列を返します。これは、配列が可変であり、スレッドセーフにするために毎回新しいコピーを返す必要があるためです。

于 2012-07-09T18:44:59.027 に答える
1

列挙型はスレッドセーフであることが保証されており、不変です。したがって、スレッドは列挙型の状態を変更できません。

2番目のケースでは、として定義するとfinal、スレッドセーフにもなり、エラーの参照を変更することはできません。

「参照」のみを変更することはできませんが、配列の状態を変更することはできます。

于 2012-07-09T18:44:40.430 に答える
1

values()他の人は、メソッドが毎回新しい配列を返すことをすでに指摘しているので、スレッドセーフです。

ただし、2番目の質問に答えるには:

これらの値のサブセットを使用して静的配列変数を定義する場合、それはスレッドセーフですか?

いいえ 。配列要素は常に変更可能であるため、どの配列も安全ではありません。 public staticつまり、任意のスレッドがTYPES[0]他のスレッドに変更される可能性がありますType。これは、複数のスレッドが存在する場合、または実際にはシングルスレッドプログラムの場合でも安全ではありません。

を公​​開する方がはるかに優れてList<Type>います。これを安全に不変にすることができます(たとえば、を使用してCollections.unmodifiableList())。

于 2012-07-09T18:47:59.387 に答える