class MyClass
{
private static volatile Resource resource;
public static Resource getInstance()
{
if(resource == null)
resource = new Resource();
return resource;
}
}
Here if the Resource is a immutable class, is it safe to write the above code? As in java concurrency in practice it's mentioned that "initialization safety allow properly constructed immutable objects to be safely shared across thread.So the above code is safe to be written." (in page no 349 16.3). But with this it may possible if two threads checks for the null and they can proceed for object creation which is against the invariant of the class (singleton). please explain. A continuation of the question in link
No, this is not threadsafe code. In this case, Resource
might be threadsafe, but your getInstance
method is not.
Imagine this sequence of events
Thread1 calls getInstance and checks "if resource == null" and then stops (because the OS said it was time for it to be done) before initializing the resources.
Thread2 calls getInstance and checks "if resource == null" and then initializes the instance
Now Thread1 starts again and it also initializes the instance.
It has now been initialized twice and is not a singleton.
You have a couple of options to make it thread safe.
Make the getInstance
method synchronized
Initialize the instance on declaration (or in a static initializer), and getInstance
can just return it.
You also don't need to make the variable volatile. In case #1, synchronizing the method flushes the variable anyway so all variables will see an updated copy. In case #2, the object is guaranteed to be visible to all objects after construction.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.