The situation is the following:
- I have an object with lots of setters and getters.
- Instance of this object is created in a one particular thread where all values are set. Initially I create an "empty" object using new statement and only then I call some setters methods based on some complicated legacy logic.
- Only then this object became available to all other threads that use only getters.
The question: Do I have to make all variables of this class volatile or not?
Concerns:
- Creation of a new instance of the object and setting all its values is separated in time.
- But all other threads have no idea about this new instance until all values are set. So other threads shall not have a cache of not fully initialized object. Isn't it?
Note: I am aware about builder pattern, but I cannot apply it there for several other reasons :(
EDITED: As I feel two answers from Mathias and axtavt do not match very well, I would like to add an example:
Let's say we have a foo class:
class Foo {
public int x=0;
}
and two threads are using it as described above:
// Thread 1 init the value:
Foo f = new Foo();
f.x = 5;
values.add(f); // Publication via thread-safe collection like Vector or Collections.synchronizedList(new ArrayList(...)) or ConcurrentHashMap?.
// Thread 2
if (values.size()>0){
System.out.println(values.get(0).x); // always 5 ?
}
As I understood Mathias, it can print out 0 on some JVM according to JLS. As I understood axtavt it will always print 5.
What is your opinion?
-- Regards, Dmitriy