標籤:
1.何為單例模式?
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例類的特殊類。通過單例模式可以保證系統中一個類只有一個執行個體而且該執行個體易於外界訪問,從而方便對執行個體個數的控制並節約系統資源。如果希望在系統中某個類的對象只能存在一個,單例模式是最好的解決方案。單例模式確保一個類只有一個執行個體,自行提供這個執行個體並向整個系統提供這個執行個體。
2.單例模式的實現方式
一般來說單例設計模式有三個具體的實現方式,分別為懶漢模式,饑漢模式以及雙重鎖設計模式。
下面我們將要分別介紹它們:
1、懶漢模式
懶漢式是典型的時間換空間,就是每次擷取執行個體都會進行判斷,看是否需要建立執行個體,浪費判斷的時間。當然,如果一直沒有人使用的話,那就不會建立實 例,則節約記憶體空間。
java代碼執行個體如下:
package com.yonyou.test; /** * 使用懶漢模式建立一個單例模式 * @author 小浩 * @建立日期 2015-4-4 */public class Singleton {private static Singleton instance=null;/*** 返回或者建立相關的單例執行個體* @return*/public static synchronized Singleton getInstance(){//使用同步方法保證安全執行緒if(instance==null){instance=new Singleton();}return instance;}/*** 一個私人的構造方法,使外部的對象不能new相關的執行個體,* 這個尤其要注意,一定要提供預設的私人化的方法去覆蓋* 預設的構造方法 否則的話,如果使用者直接去new一個對象* 的話,就無法保證單例了~~~*/private Singleton(){}}
咋一看這代碼感覺還可以,已經基本實現了單例的設計模式,但是如果我們仔細推敲的話,我們就會發現問題所在。
在代碼
public static synchronized Singleton getInstance(){//使用同步方法保證安全執行緒
這裡我們看到,每次擷取單例的時候都會加入同步鎖,這樣的話勢必會造成訪問效能的問題。
為了更好的解決這個問題,我們可以修改加入同步鎖的位置,請看下面的代碼:
package com.yonyou.test; /** * 使用懶漢模式建立一個單例模式 * @author 小浩 * @建立日期 2015-4-4 */public class Singleton {private static Singleton instance=null;/*** 返回或者建立相關的單例執行個體* @return*/public static Singleton getInstance(){if(instance==null){ //加入同步代碼塊,這樣可以有效處理並發下訪問問題 synchronized(Singleton.class){ if(instance==null){ instance=new Singleton(); } }}return instance;}/*** 一個私人的構造方法,使外部的對象不能new相關的執行個體,* 這個尤其要注意,一定要提供預設的私人化的方法去覆蓋* 預設的構造方法 否則的話,如果使用者直接去new一個對象* 的話,就無法保證單例了~~~*/private Singleton(){}}
此外還有一個比較給力的實現單例的方式,推薦大家使用這種方式:
Google公司的工程師Bob Lee寫的新的懶漢單例模式,這裡單例模式是在內部類的基礎上實現的,相應的安全執行緒是由JVM靜態初始化器來完成。
package com.yonyou.test; /** * 使用懶漢模式建立一個單例模式 * @author 小浩 * @建立日期 2015-4-4 */public class Singleton { /*** 類級的內部類,也就是靜態成員式內部類,該內部類的執行個體與外部類的執行個體* 沒有綁定關係,而且只有被調用到時才會裝載,從而實現了消極式載入。*/ static class SingletonHolder { /** * 靜態初始化器,由JVM來保證安全執行緒 */ static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } /** * 一個私人的構造方法,使外部的對象不能new相關的執行個體, * 這個尤其要注意,一定要提供預設的私人化的方法去覆蓋 * 預設的構造方法 否則的話,如果使用者直接去new一個對象 * 的話,就無法保證單例了~~~ */private Singleton(){}}
3.餓漢的設計模式
在初始化類的過程中就會完成相關執行個體的初始化,一般認為這種方式要更加安全些,餓漢式是典型的空間換時間,當類裝載的時候就會建立類的執行個體,不管你用不用,先建立出來,然後每次調用的時候,就不需要再判斷,節省了已耗用時間。
Java代碼執行個體如下:
package com.yonyou.test; /** * 使用饑漢模式建立一個單例模式 * @author 小浩 * @建立日期 2015-4-4 */public class Singleton {//在載入類的時候就初始化Singleton執行個體private final static Singleton instance=new Singleton();/*** 返回或者建立相關的單例執行個體* @return*/public static Singleton getInstance(){ return instance;}/*** 一個私人的構造方法,使外部的對象不能new相關的執行個體,* 這個尤其要注意,一定要提供預設的私人化的方法去覆蓋* 預設的構造方法 否則的話,如果使用者直接去new一個對象* 的話,就無法保證單例了~~~*/private Singleton(){}}
Java常見設計模式之單例模式