new 操做的底層過程: java
1. 爲對象分配內存空間多線程
2. 初始化對象jvm
3. 將內存空間地址賦給對象引用變量線程
注意,上述過程的 2,3 次序可能會顛倒。所以,在多線程的環境下直接 new Instance() 會出現問題,,即線程2訪問對象的時候該對象還未初始化。而用 volatile 修飾對象可強制 2,3過程不會從新排序。 (jdk 5 以上) code
** 然而,你不能保證全部的jvm都很好的實現了 這個內存模型,因此這可能仍是會有一些問題。因此最可靠的方式仍是用static (惡漢式)對象
package designpattern.singleton; /** * 使用雙重檢查鎖定 機制實現單例模式 * @author Administrator * */ public class Singleton { /** * 這裏要加 volatile修飾,保證在對象初始化後纔將對象引用賦值 */ private volatile static Singleton singleton; private Singleton() { } public static Singleton getInstance() { if (singleton == null) { // 第一次檢查 synchronized (Singleton.class) { if (singleton == null) // 第二次檢查 singleton = new Singleton(); } } return singleton; } }
參考:http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization排序