private volatile static Singleton instance;
public static Singleton getInstance() {
if (instance == null) {
synchronized(Singleton.class) { //1
if (instance == null) //2
instance = new Singleton(); //3
}
}
return instance;
}
看这个double-checked locking单例模式的实现,volatile关键字使用的必要性在哪里?想这问题之前,可以预读这篇文章:
http://www.ibm.com/developerworks/java/library/j-dcl.html
因为存在Out-of-order writes现象,所以这里volatile关键字是在当instance被初始化给Singleton实例时保证多线程正确地处理instance变量,那这里与线程间的可见性有关吗?
回答:
我觉得与可见性无关,因为synchronized block已经可以保证块内变量的可见性,这里应该是变量操作的原子性
For references and all primitives (except sometimes long ), two threads will always see a complete value, never one half-way modified by another thread. The official term for such an intact atomic value is a consistent value .
http://mindprod.com/jgloss/volatile.html
2010.05.28 补充:
阅此文:
http://www.ibm.com/developerworks/java/library/j-jtp06197.html
其中有说到:
Pattern #2: one-time safe publication
The visibility failures that are possible in the absence of synchronization can get even trickier to reason about when writing to object references instead of primitive values. In the absence of synchronization, it is possible to see an up-to-date value for an object reference that was written by another thread and still see stale values for that object's state. (This hazard is the root of the problem with the infamous double-checked-locking idiom, where an object reference is read without synchronization, and the risk is that you could see an up-to-date reference but still observe a partially constructed object through that reference.)
One technique for safely publishing an object is to make the object reference volatile. Listing 3 shows an example where during startup, a background thread loads some data from a database. Other code, when it might be able to make use of this data, checks to see if it has been published before trying to use it.
volatile在引用是最新,但对象状态是陈旧的状况下可以起到作用,保证都是最新。
2011.02.10 补充更新:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
这篇文章很不错,火龙果提供链接