Well, consider the immutable class Immutable
as given below:
public final class Immutable
{
final int x;
final int y;
public Immutable(i
So, Thread B could see the write to objas 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.
In Java 1.4, this was true. In Java 5.0 and above, final fields are thread safe after construction.
What you're describing here are two different things. First, Immutable
is thread safe if the operations are being done to an instance of it.
Thread safety is, in part, ensuring that memory isn't accidentally overwritten by another thread. Insofar as using Immutable
, you can never overwrite any data contained in an instance of it, so you can feel confident that, in a concurrent environment, an Immutable
object will be the same when you constructed it to when the threads are manipulating it.
What you've got right there is a broken implementation of double-checked locking.
You're right in that Thread A and Thread B may trample the instance before it's set, thus making the whole immutability of the object Immutable
completely moot.
I believe that the approach to fix this would be to use the volatile
keyword for your obj
field, so that Java (> 1.5) will respect the intended use of the singleton, and disallow threads to overwrite the contents of obj
.
Now, having read a bit closer, it seems to be a bit wonky that you'd have an immutable singleton that required two pieces of static data for it to exist. It seems more like this would be suited towards a factory instead.
public class Sharable {
private Sharable() {
}
public static Immutable getImmutableInstance(int a, int b) {
return new Immutable(a, b);
}
}
Every instance of Immutable
you get will truly be immutable - creating a new Immutable
has no impact on the others, and using an instance of Immutable
has no impact on any others as well.