設計模式是一套被反覆使用、多數人知曉的經過分類編目的、**設計經驗的總結。
使用設計模式是為了可重用**、讓**更容易被他人理解,保證**可靠性。
在開發過程中,有些物件,我們只需要乙個,比如:配置檔案、工具類、執行緒池、快取、日誌物件等。這些物件如果被創造出了多個例項,就會導致許多問題,例如占用過多資源,讀寫檔案不一致等。
怎麼保證整個應用中某個例項有且只有乙個?—-單例模式
單例模式的餓漢式實現
public
class singleton
//2.建立類的唯一例項---該類只要一載入就會創造乙個唯一例項---餓漢式實現
private
static singleton instance = new singleton();
//3.提供乙個用於獲取例項的方法
public
static singleton getinstance()
}
餓漢式在類載入的過程中就會建立乙個本類的靜態物件,所以它的載入過程比懶漢式慢,但是獲得類例項的過程比懶漢式快,並且它在多執行緒模式下比較安全。缺點在於沒有呼叫方法前就載入了,比較占用記憶體。
單例模式的懶漢式實現
public
class
singletonii
private
static singletonii instance;
public
static singletonii getinstance()
return instance;
}}測試類:
/** * created by dell on 2018/4/15.
* 餓漢模式載入類時比較慢,執行時,獲取物件的速度比較快。因為載入類時已經建立了類的唯一例項,執行緒安全。
* 懶漢式載入類時比較快,執行時,獲取物件的速度比較慢,而且有可能執行緒不安全。
*/public
class
singletest else
singletonii s3 = singletonii.getinstance();
singletonii s4 = singletonii.getinstance();
if (s3 == s4) else
//檢查懶漢式執行緒安全問題
//newfixedthreadpool 建立乙個定長線程池,可控制線程最大併發數,超出的執行緒會在佇列中等待。
executorservice threadpool = executors.newfixedthreadpool(1000);
for (int i = 0; i < 1000; i++)
});}
}}
對於singletonii**注釋部分,如果此時有兩個執行緒,執行緒a執行到1處,讀取了instance為null,然後cpu就被執行緒b搶去了,此時,執行緒a還沒有對instance進行例項化。因此,執行緒b讀取instance時仍然為null,於是,它對instance進行例項化了。然後,cpu就被執行緒a搶去了。此時,執行緒a由於已經讀取了instance的值並且認為它為null,所以,再次對instance進行例項化。所以,執行緒a和執行緒b返回的不是同乙個例項。
引發了單例模式的執行緒不安全問題。
解決方式:用synchronized修飾獲取例項的方法
/**
* created by dell on 2018/4/15.
* 單例模式的懶漢式實現
*/public
class
singletonii
private
static
volatile singletonii instance;
//雙重檢查加鎖機制
public
static
synchronized singletonii getinstance() }}
return instance;
}}
雙重加鎖機制配合volatile關鍵字。
instance = new singletonii()其實可以分為下面的步驟:
1.申請一塊記憶體空間;
2.在這塊空間裡例項化物件;
3.instance的引用指向這塊空間位址;
指令重排序存在的問題是:
對於以上步驟,指令重排序很有可能不是按上面123步驟依次執行的。比如,先執行1申請一塊記憶體空間,然後執行3步驟,instance的引用去指向剛剛申請的記憶體空間位址,那麼,當它再去執行2步驟,判斷instance時,由於instance已經指向了某一位址,它就不會再為null了,因此,也就不會例項化物件了。這就是所謂的指令重排序安全問題。那麼,如何解決這個問題呢?加上volatile關鍵字,因為volatile可以禁止指令重排序。
Java設計模式 單例模式
單例模式 singleton 顧名思義,就是乙個類只有乙個例項。作為物件的建立模式,單例模式確保某乙個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。這個類稱為單例類。顯然單例模式的要點有三個 一是某個類只能有乙個例項 二是它必須自行建立這個例項 三是它必須自行向整個系統提供這個例項。從具體...
java設計模式 單例模式
這個模式是很有意思,而且比較簡單,但是我還是要說因為它使用的是如此的廣泛,如此的有人緣,單例就是單 一 獨苗的意思,那什麼是獨乙份呢?你的思維是獨乙份,除此之外還有什麼不能山寨的呢?我們舉個比較難複製的物件 皇帝中國的歷史上很少出現兩個皇帝並存的時期,是有,但不多,那我們就認為皇帝是個單例模式,在這...
java設計模式 單例模式
單例模式介紹 單例模式分 懶漢式單例 餓漢式單例。單例模式有一下特點 1 單例類只能有乙個例項。2 單例類必須自己自己建立自己的唯一例項。3 單例類必須給所有其他物件提供這一例項。單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。單例有併發問題,只有乙個例項,多個執行緒就可能同...