What is the point of making the singleton instance volatile while using double lock? [duplicate]

寵の児 提交于 2020-01-09 06:01:08

问题


private volatile static Singleton uniqueInstance

In a singleton when using double lock method for synchronization why is the single instance declared as volatile ? Can I achieve the same functionality without declaring it as volatile ?


回答1:


Without volatile the code doesn't work correctly with multiple threads.

From Wikipedia's Double-checked locking:

As of J2SE 5.0, this problem has been fixed. The volatile keyword now ensures that multiple threads handle the singleton instance correctly. This new idiom is described in The "Double-Checked Locking is Broken" Declaration:

// Works with acquire/release semantics for volatile
// Broken under Java 1.4 and earlier semantics for volatile
class Foo {
    private volatile Helper helper = null;
    public Helper getHelper() {
        Helper result = helper;
        if (result == null) {
            synchronized(this) {
                result = helper;
                if (result == null) {
                    helper = result = new Helper();
                }
            }
        }
        return result;
    }

    // other functions and members...
}

In general you should avoid double-check locking if possible, as it is difficult to get right and if you get it wrong it can be difficult to find the error. Try this simpler approach instead:

If the helper object is static (one per class loader), an alternative is the initialization on demand holder idiom

// Correct lazy initialization in Java 
@ThreadSafe
class Foo {
    private static class HelperHolder {
       public static Helper helper = new Helper();
    }

    public static Helper getHelper() {
        return HelperHolder.helper;
    }
}



回答2:


The volatile prevents memory writes from being re-ordered, making it impossible for other threads to read uninitialized fields of your singleton through the singleton's pointer.

Consider this situation: thread A discovers that uniqueInstance == null, locks, confirms that it's still null, and calls singleton's constructor. The constructor makes a write into member XYZ inside Singleton, and returns. Thread A now writes the reference to the newly created singleton into uniqueInstance, and gets ready to release its lock.

Just as thread A gets ready to release its lock, thread B comes along, and discovers that uniqueInstance is not null. Thread B accesses uniqueInstance.XYZ thinking that it has been initialized, but because the CPU has reordered writes, the data that thread A has written into XYZ has not been made visible to thread B. Therefore, thread B sees an incorrect value inside XYZ, which is wrong.

When you mark uniqueInstance volatile, a memory barrier is inserted. All writes initiated prior to that of uniqueInstance will be completed before the uniqueInstance is modified, preventing the reordering situation described above.




回答3:


To avoid using double locking, or volatile I use the follow

enum Singleton {
     INSTANCE;
}

Creating the instance is simple, lazy loaded and thread safe.




回答4:


Write to a volatile field will happen before any read operation. Below is an example code for better understanding:

private static volatile ResourceService resourceInstance;
//lazy Initialiaztion
public static ResourceService getInstance () {
    if (resourceInstance == null) { // first check
        synchronized(ResourceService.class) {
            if (resourceInstance == null) { // double check
                // creating instance of ResourceService for only one time
                resourceInstance = new ResourceService ();                    
            }
        }
    }
    return resourceInstance;
}

This link can serve you better http://javarevisited.blogspot.com/2011/06/volatile-keyword-java-example-tutorial.html




回答5:


You can use the follow code:

private static Singleton uniqueInstance;

public static synchronized Singleton getInstance(){
    if(uniqueInstance == null){
        uniqueInstance = new Singleton();
    }
    return uniqueInstance
}


来源:https://stackoverflow.com/questions/11639746/what-is-the-point-of-making-the-singleton-instance-volatile-while-using-double-l

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!