Java筆記5 單例模式

2021-09-07 10:41:27 字數 3051 閱讀 2903

一、應用楊景

在計算機系統中,執行緒池、快取、日誌物件、對話方塊、印表機、顯示卡的驅動程式物件常被設計成單例。這些應用都或多或少具有資源管理器的功能。每台計算機可以有若干個印表機,但只能有乙個printer spooler,以避免兩個列印作業同時輸出到印表機中。每台計算機可以有若干通訊埠,系統應當集中管理這些通訊埠,以避免乙個通訊埠同時被兩個請求同時呼叫。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。

二、特點

1、單例類只能有乙個例項。

2、單例類必須自己建立自己的唯一例項。

3、單例類必須給所有其他物件提供這一例項。

三、懶漢式單例

//懶漢式單例類.在第一次呼叫的時候例項化自己

public class singleton 

private static singleton single=null;

public static singleton getinstance()

return single;}}

singleton通過將構造方法限定為private避免了類在外部被例項化,在同乙個虛擬機器範圍內,singleton的唯一例項只能通過getinstance()方法訪問。

但是以上懶漢式單例的實現沒有考慮執行緒安全問題,它是執行緒不安全的,併發環境下很可能出現多個singleton例項,要實現執行緒安全,有以下三種方式,都是對getinstance這個方法改造,保證了懶漢式單例的執行緒安全。

1、在getinstance方法上加同步

public class singleton 

private static singleton single=null;

public static synchronized singleton getinstance()

return single;}}

2、雙重檢查鎖定

public class singleton 

private static singleton single=null;

public static singleton getinstance() }}

return singleton;}}

3、靜態內部類
public class singleton 

private singleton (){}

public static final singleton getinstance()

}

這3種方法的區別:

第1種,在方法呼叫上加了同步,雖然執行緒安全了,但是每次都要同步,會影響效能,畢竟99%的情況下是不需要同步的。

第2種,在getinstance中做了兩次null檢查,確保了只有第一次呼叫單例的時候才會做同步,這樣也是執行緒安全的,同時避免了每次都同步的效能損耗。

第3種,利用了classloader的機制來保證初始化instance時只有乙個執行緒,所以也是執行緒安全的,同時沒有效能損耗,建議使用這一種。

四、餓漢式單例

//餓漢式單例類.在類初始化時,已經自行例項化 

public class singleton1

private static final singleton1 single = new singleton1();

//靜態工廠方法

public static singleton1 getinstance()

}

餓漢式在類建立的同時就已經建立好乙個靜態的物件供系統使用,以後不再改變,所以天生是執行緒安全的。

五、餓漢式和懶漢式區別

從名字上來說,餓漢就是類一旦載入,就把單例初始化完成,保證getinstance的時候,單例是已經存在的了;而懶漢比較懶,只有當呼叫getinstance的時候,才回去初始化這個單例。

另外從以下兩點再區分以下這兩種方式:

1、執行緒安全:

餓漢式天生就是執行緒安全的,可以直接用於多執行緒而不會出現問題,

懶漢式本身是非執行緒安全的,為了實現執行緒安全有幾種寫法,分別是上面的1、2、3,這三種實現在資源載入和效能方面有些區別。

2、資源載入和效能:

餓漢式在類建立的同時就例項化乙個靜態物件出來,不管之後會不會使用這個單例,都會佔據一定的記憶體,但是相應的,在第一次呼叫時速度也會更快,因為其資源已經初始化完成;而懶漢式顧名思義,會延遲載入,在第一次使用該單例的時候才會例項化物件出來,第一次呼叫時要做初始化,如果要做的工作比較多,效能上會有些延遲,之後就和餓漢式一樣了。

六、什麼是執行緒安全?

如果你的**所在的程序中有多個執行緒在同時執行,而這些執行緒可能會同時執行這段**。如果每次執行結果和單執行緒執行的結果是一樣的,而且其他的變數的值也和預期的是一樣的,就是執行緒安全的。

或者說:乙個類或者程式所提供的介面對於執行緒來說是原子操作,或者多個執行緒之間的切換不會導致該介面的執行結果存在二義性,也就是說我們不用考慮同步的問題,那就是執行緒安全的。

七、應用

以下是乙個單例類使用的例子,以懶漢式為例,這裡為了保證執行緒安全,使用了雙重檢查鎖定的方式:

class singleton 

private static volatile singleton instance = null;

public static singleton getinstance() }}

return instance;

}public string getname()

public void setname(string name)

public void printinfo()

}public class testsingleton else}}

執行結果:

這裡可以看出,兩次建立的是同乙個例項,第一次name值為zhang san,第二次name值為lisi。第二次的值覆蓋了第一次的值,所以最終name的值為lisi。

結論:由結果可以得知單例模式為乙個物件導向的應用程式提供了物件惟一的訪問點,不管它實現何種功能,整個應用程式都會同享乙個例項物件。

5 java單例模式

1 什麼是單例模式 構造方法私有化 靜態屬性指向例項 使用公共的靜態方法將屬性返回出去 分為餓漢式和懶漢式 2 餓漢式舉例 public class singleton 2 新建乙個類屬性 類屬性只能有乙個 指向要例項化的物件 private static singleton singleton n...

設計模式筆記5(單例模式)

有的時候一些資源是只能有乙個的,這時候,代表這個資源的物件就只能有乙個,例如執行緒池。快取等資源。有人會說直接用全域性變數來實現不就是,這種情況是可以的,但是這樣是有缺點的,全域性變數在程式一開始的時候就建立好物件,但是,有些資源是十分消耗資源的,這樣的話浪費大量資源。經典的模式 如下 public...

設計模式筆記5(單例模式)

有的時候一些資源是只能有乙個的,這時候,代表這個資源的物件就只能有乙個,例如執行緒池。快取等資源。有人會說直接用全域性變數來實現不就是,這種情況是可以的,但是這樣是有缺點的,全域性變數在程式一開始的時候就建立好物件,但是,有些資源是十分消耗資源的,這樣的話浪費大量資源。經典的模式 如下 public...