java設計模式 單例模式 執行緒安全的懶漢式

2021-08-18 19:41:31 字數 2415 閱讀 9342

設計模式是一套被反覆使用、多數人知曉的經過分類編目的、**設計經驗的總結。

使用設計模式是為了可重用**、讓**更容易被他人理解,保證**可靠性。

在開發過程中,有些物件,我們只需要乙個,比如:配置檔案、工具類、執行緒池、快取、日誌物件等。這些物件如果被創造出了多個例項,就會導致許多問題,例如占用過多資源,讀寫檔案不一致等。

怎麼保證整個應用中某個例項有且只有乙個?—-單例模式

單例模式的餓漢式實現

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 單例類必須給所有其他物件提供這一例項。單例模式確保某個類只有乙個例項,而且自行例項化並向整個系統提供這個例項。單例有併發問題,只有乙個例項,多個執行緒就可能同...