Johnny
Johnny

Reputation: 1569

Can the following Singleton be unsafe in multithreaded environment

I want to be sure that my Singleton instance is available safely and with minimum synchronization but I have doubt about the first if clause outside the synchronized block. Is it possible for the INSTANCE to have a not-null value when it isn't completely constructed? If so how can I solve the issue.

I think that including the whole get() block will reduce the efficiency because there will be so many configuration variables that must be read thousands of times per second from different part of program via this get() method.

public class ConfsDBLoader {

    private static ConfsDBLoader INSTANCE = null;
    private static final Object lock = new Object();

    private ConfsDBLoader() { //Codes loading the db objects
    }

    public static ConfsDBLoader get(){
        if(INSTANCE != null){
            return INSTANCE;
        } else {
            synchronized(lock){
                if(INSTANCE == null){
                    INSTANCE = new ConfsDBLoader();
                }
                return INSTANCE;
            }
        }
    }

}

NOTE: I cant use static initialization because my hibernate sessionFactory is initialized statically and I want to have complex static structures that need each other. In fact I already have it and I'm not interested to make it more and more complex and investigate where these these static attributes try to use each other.

Upvotes: 0

Views: 132

Answers (1)

user2982130
user2982130

Reputation:

No. There is not enough synchronization to make sure that you are seeing the correct value on INSTANCE. You may see a non-null, but corrupt instance if your ConfsDBLoader because it may not be properly constructed by the time another thread calls getInstance().

You have 3 choices:

  • Eager initialize and make final
  • Synchronize whole method
  • Make INSTANCE volatile

Upvotes: 2

Related Questions