Well, consider the immutable class Immutable
as given below:
public final class Immutable
{
final int x;
final int y;
public Immutable(int x,int y)
{
this.x = x;
this.y = y;
}
//Setters
public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
}
Now I am creating an object of Immutable
in a class Sharable
whose object is going to be shared by multiple threads:
public class Sharable
{
private static Immutable obj;
public static Immutable getImmutableObject()
{
if (obj == null) --->(1)
{
synchronized(this)
{
if(obj == null)
{
obj = new Immutable(20,30); ---> (2)
}
}
}
return obj; ---> (3)
}
}
Thread A
sees the obj
as null
and moves into the synchronized block and creates object. Now, Since The Java Memory Model (JMM) allows multiple threads to observe the object after its initialization has begun but before it has concluded. So, Thread B
could see the write to obj
as occurring before the writes to the fields of the Immutable
. Hence Thread B
could thus see a partially constructed Immutable
that may well be in an invalid state and whose state may unexpectedly change later.
Isn't it making Immutable
non-thread-safe ?
EDIT
OK, After having lot of look up on SO and going thorough some comments,I got to know that You can safely share a reference to an immutable object between threads after the object has been constructed. Also, as mentioned by @Makoto, it is usually required to declare the fields containing their references volatile to ensure visibility. Also , as stated by @PeterLawrey , declaring the reference to immutable object as final
makes the field as thread-safe