0

Possible Duplicate:
How thread-safe is enum in java?

Let there be an enum class like

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

Is the Type.values() array thread safe to access in a for loop, e.g., in a static method? For example:

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

Furthermore, if one defines a static array variable with any subset of these values, will that be thread safe to read? For example:

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

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

In both cases, the process() method may belong to a different class than the definition of the Type enum and of the types array.

Also, the TYPES array could be defined once in the Type enum and returned by a static method of that enum.

So, given the above, if multiple threads are running the process() method simultaneously, will the code be thread safe (at least for just reading the values of the TYPES array)?

Community
  • 1
  • 1
PNS
  • 19,295
  • 32
  • 96
  • 143
  • I have read that question, it is not identical to mine. :-) – PNS Jul 09 '12 at 18:41
  • How do you think it's different? Looks the same to me. Enums are guaranteed to be thread-safe in Java, there is no way to modify the values of an enum at runtime so you can be guaranteed that iterating the types will be safe. – jjathman Jul 09 '12 at 18:44
  • This is what I wan to confirm, actually. – PNS Jul 09 '12 at 18:50

3 Answers3

3

The method Type.values() returns a new array every time. It does this because the array is mutable and it has to return a new copy each time to be thread safe.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Which is exactly why I am wondering if reusing the same subset of values() in a static array can be thread safe. – PNS Jul 09 '12 at 19:41
  • Its only an issue if you write to the same copy in multiple threads. If you call `values()` each time or you don't modify your copy, you won't have a problem. – Peter Lawrey Jul 09 '12 at 19:58
  • Yes, read-only seems to be thread safe. – PNS Jul 09 '12 at 20:04
1

enum are guaranteed thread-safe they are immutable. So, threads can't modify the state of the enum.

Second case, when you define as final, there also it will be threadsafe, you are not allowed to modify the reference of error.

Remember, you are not allowed to change the "reference" only, but you can change the state of array.

kosa
  • 65,990
  • 13
  • 130
  • 167
1

Others have already pointed out that the values() method returns a new array each time, so it is thread safe.

However, to answer your second question:

if one defines a static array variable with any subset of these values, will that be thread safe?

No. Any public static array is not safe, because array elements are always mutable. That is, any thread could change TYPES[0] to be any other Type, which is not safe in the presence of multiple threads -- or indeed even in a single-threaded program.

Much better would be to expose a List<Type>, which can then be safely made immutable (e.g., using Collections.unmodifiableList()).

Community
  • 1
  • 1
Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • I am using arrays for maximum performance. If the array is only used for reading, will it be thread safe? – PNS Jul 09 '12 at 18:51
  • 1
    @PNS: I prefer to always be conservative on matters of thread and memory safety, and assume that if something is possible under the rules of the language that some code is doing it somewhere. Generally, never use an array (a collection of *variables*) where a `List` (a collection of *values*) would do. See also Eric Lippert's excellent article [Arrays Considered Somewhat Harmful](http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx). – Daniel Pryden Jul 09 '12 at 18:53
  • You are right, of course, but is it thread safe to just read it? :-) – PNS Jul 09 '12 at 18:55
  • @PNS: If you can guarantee that all threads in the program never mutate the contents of the array and only ever read from it, then it is safe. But since it is marked `public`, **you cannot guarantee that**. Therefore it is not safe. – Daniel Pryden Jul 09 '12 at 18:58
  • Fair enough, but if Java needs to create a **new** array for values() each time, for thread safety reasons, how would using the same array of some of these values could be thread-safe, even for read-only purposes? – PNS Jul 09 '12 at 19:40
  • @PNS: The `values()` method creates a new array every time because the array is escaping its control. Nothing prevents you from doing `Type.values()[0] = null;` -- it's a perfectly legal statement, and the `values()` method has no way to prevent it from happening. If the `values()` method re-used the array, it would mean that the actions of one of its callers could change the value returned to a different caller. This is very fragile and can lead to subtle bugs and serious vulnerabilities. This isn't really a matter of *thread* safety per se, but rather of code safety in general. – Daniel Pryden Jul 09 '12 at 20:34