設計模式學習筆記之單例模式
設計模式中最簡單的模式就要數單例模式了。
那麼什麼是單例模式呢? 保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。
上圖為單例模式的結構示意圖。
那麼為什麼要使用單例模式呢?
簡單來說:單例模式的存在,一則,解決多執行緒併發訪問的問題。二則,節約系統記憶體,提交系統執行的效率,提高系統效能。
下面我們就來看看程式中是怎麼實現單例模式的:
一般我們設計一個類都是這樣的:
public class Abc
{
private Abc()
{
};
}
然後在其他部分呼叫:
public class Cbd
{
public Cbd()
{
Abc n1,n2;
n1=new Abc();
n2=new Abc();
}
}
public class Abc{
private static Abc uniqeInstance_Abc = null; //通過內建私有靜態引數實現單例狀態
private Abc(){
};
//外部只能呼叫單例,單例實體有類內部控制
public static Abc getInstance_Abc()
{
if(uniqeInstance_Abc==null)
{
uniqeInstance_Abc=new Abc();
}
return uniqeInstance_Abc;
}
}
public class Cbd
{
public Cbd()
{
Abc n1,n2;
n1=Abc.getInstance_Abc();
}
}
寫一個小例子,模擬一下我們計算機中的CPU處理程式:
package com.java.jikexueyuan.singleton;
public class Cpu {
private boolean idle;
private boolean compute;
public volatile static Cpu uniqueInstance_cpu = null;
int num;
private Cpu() {
idle = true;
compute = false;
num = 101;
}
public static Cpu getInstance() {
if (uniqueInstance_cpu == null) {
synchronized (Cpu.class) {
if (uniqueInstance_cpu == null) {
uniqueInstance_cpu = new Cpu();
}
}
}
return uniqueInstance_cpu;
}
//判斷cpu是否為空閒狀態
public boolean isIdle() {
if (idle) {
idle = false;
compute = false;
System.out.println("cpu空閒");
return true;
}
else
{
System.out.println("cpu繁忙");
return true;
}
}
//cpu計算結束
public void compute_over() {
if ((!idle) && compute) {
idle = true;
compute = false;
System.out.println("cpu計算完成");
}
}
//啟動cpu計算過程
public void computing() {
if ((!idle) && (!compute)) {
compute = true;
System.out.println("cpu正在計算,計算cpu編號為" + num);
}
}
}
我們來呼叫一下:
public class test {
public static void main(String[] args)
{
for(int i = 0; i < 5 ; i++)
{
Cpu c1 = Cpu.getInstance();
if(c1.isIdle())
{
c1.computing();
c1.compute_over();
}
}
}
}
其實這樣設計的單例模式有一個重大隱患,就是當兩個執行緒同時建立一個Abc類的時候,可以會new出來兩個實體而導致嚴重的錯誤。。。
解決傳統的解決方式呢,有三種:
第一種:新增同步鎖:
public class Abc{
private static Abc uniqeInstance_Abc = null; //通過內建私有靜態引數實現單例狀態
private Abc(){
};
//外部只能呼叫單例,單例實體有類內部控制
//新增了同步所,保證不會有兩個執行緒同是進入該方法
public static synchronized Abc getInstance_Abc()
{
if(uniqeInstance_Abc==null)
{
uniqeInstance_Abc=new Abc();
}
return uniqeInstance_Abc;
}
}
public class Abc{
//通過內建私有靜態引數實現單例狀態
//直接建立例項
private static Abc uniqeInstance_Abc = new Abc();
private Abc(){
};
//外部只能呼叫單例,單例實體有類內部控制
public static Abc getInstance_Abc()
{
if(uniqeInstance_Abc==null)
{
uniqeInstance_Abc=new Abc();
}
return uniqeInstance_Abc;
}
}
public class Abc{
//通過內建私有靜態引數實現單例狀態
//volatile關鍵字確保多執行緒在處理時的正確性
private volatile static Abc uniqeInstance_Abc = new Abc();
private Abc(){
};
//外部只能呼叫單例,單例實體有類內部控制
public static Abc getInstance_Abc()
{
//多重加鎖
if (uniqeInstance_Abc == null) {
synchronized (Abc.class) {
if (uniqeInstance_Abc == null) {
uniqeInstance_Abc = new Abc();
}
}
}
return uniqeInstance_Abc;
}
}
單例模式的使用場景:
1.資源共享的情況下,避免由於資源操作時導致的效能或損耗等。如上述中的日誌檔案,應用配置。
2.控制資源的情況下,方便資源之間的互相通訊。如執行緒池等。
相關文章
- 設計模式學習筆記——單例模式設計模式筆記單例
- Java設計模式學習筆記(五) 單例模式Java設計模式筆記單例
- 設計模式學習之單例模式設計模式單例
- JavaScript設計模式學習之單例模式JavaScript設計模式單例
- java/android 設計模式學習筆記(1)--- 單例模式JavaAndroid設計模式筆記單例
- 小學生學習設計模式之單例模式設計模式單例
- 設計模式學習筆記之策略模式設計模式筆記
- 設計模式學習-單例模式設計模式單例
- 設計模式之“物件效能模式”: Singleton 單例模式(筆記)設計模式物件單例筆記
- 設計模式學習筆記之工廠模式設計模式筆記
- 設計模式學習筆記之迭代器模式設計模式筆記
- 設計模式學習筆記之狀態模式設計模式筆記
- 我學設計模式 之 單例模式設計模式單例
- 設計模式學習筆記之裝飾者模式設計模式筆記
- 設計模式學習筆記之介面卡模式設計模式筆記
- 設計模式快速學習(三)單例模式設計模式單例
- 學習筆記-設計模式:MVC模式筆記設計模式MVC
- 3.[研磨設計模式筆記]單例模式設計模式筆記單例
- 設計模式之☞單例模式設計模式單例
- 設計模式之單例模式設計模式單例
- 設計模式之---單例模式設計模式單例
- 設計模式之單例設計模式設計模式單例
- 設計模式學習(一)單例模式補充——單例模式析構設計模式單例
- 設計模式之單例模式(《JavaScript設計模式與開發實踐》讀書筆記)設計模式單例JavaScript筆記
- 設計模式學習筆記設計模式筆記
- 學習筆記-設計模式筆記設計模式
- 從JavaScript學習設計模式-02單例模式JavaScript設計模式單例
- Java設計模式學習筆記(二) 簡單工廠模式Java設計模式筆記
- 設計模式學習筆記(四)單例模式的實現方式和使用場景設計模式筆記單例
- PHP 設計模式之單例模式PHP設計模式單例
- Javascript 設計模式之單例模式JavaScript設計模式單例
- Javascript設計模式之單例模式JavaScript設計模式單例
- js設計模式之單例模式JS設計模式單例
- PHP 設計模式之——單例模式PHP設計模式單例
- 01 設計模式之單例模式設計模式單例
- 設計模式(一)之單例模式設計模式單例
- golang設計模式之單例模式Golang設計模式單例
- PHP設計模式之單例模式PHP設計模式單例