單例模式(Singleton)的同步鎖synchronized
阿新 • • 發佈:2017-11-02
靜態方法 兩種 餓漢 初始化 同步方法 上線 懶漢式 urn 同步鎖
單例模式,有“懶漢式”和“餓漢式”兩種。
懶漢式
單例類的實例在第一次被引用時候才被初始化。
public class Singleton { private static Singleton instance=null; private Singleton() { } public static Singleton getInstance(){ if (instance == null) { instance = new Singleton(); } return instance; } }
餓漢式
單例類的實例在加載的時候就被初始化。
public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance(){ return instance; } }
在單線程程序中,上面兩種形式基本可以滿足要求了,但是在多線程環境下,單例類就有可能會失效,這個時候就要對其加鎖了,來確保線程安全。
對線程加鎖用的synchronized關鍵字,這個關鍵字的用法主要也分為兩種:
一種是加在方法名之前,形如:synchronized methodeName(params){……};
二是聲明同步塊,形如:synchronized(this){……};
下面是對懶漢式單例類加上線程同步的實現:
同步方法:
public class Singleton { private static Singleton instance=null; private Singleton() { } public synchronized static Singleton getInstance(){ if (instance == null) { instance = new Singleton(); } return instance; } }
這種方式效率比較低,性能不是太好,不過也可以用,因為是對整個方法加上了線程同步,其實只要在new的時候考慮線程同步就行了,這種方法不推薦使用。
同步代碼塊:
public class Singleton { private static Singleton instance; private final static Object syncLock = new Object(); private Singleton() { } public static Singleton getInstance(){ if (instance == null) { synchronized (syncLock) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
synchronized同步塊括號中的鎖定對象是采用的一個無關的Object類實例,而不是采用this,因為getInstance是一個靜態方法,在它內部不能使用未靜態的或者未實例的類對象,因此也可以用下面的方法來實現:
public class Singleton { private static Singleton instance; private Singleton() { } public static Singleton getInstance(){ if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
單例模式(Singleton)的同步鎖synchronized