简体   繁体   中英

singleton with immutable class in java

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.

  1. Make the getInstance method synchronized

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM