所謂單例,指的就是單例項,有且僅有乙個類例項,這個單例不應該由人來控制,而應該由**來限制,強制單例。
單例有其獨有的使用場景,一般是對於那些業務邏輯上限定不能多例只能單例的情況,例如:類似於計數器之類的存在,一般都需要使用乙個例項來進行記錄,若多例計數則會不準確。
其實單例就是那些很明顯的使用場合,沒有之前學習的那些模式所使用的複雜場景,只要你需要使用單例,那你就使用單例,簡單易理解。
所以我認為有關單例模式的重點不在於場景,而在於如何使用。
1、常見的單例模式有兩種建立方式:懶漢式與餓漢式
(1)懶漢式
何為懶?顧名思義,就是不做事,這裡也是同義,懶漢式就是不在系統載入時就建立類的單例,而是在第一次使用例項的時候再建立。
詳見下方**示例:
public class lhandanli
//定義乙個公共的公開的方法來返回該類的例項,由於是懶漢式,需要在第一次使用時生成例項,所以為了執行緒安全,使用synchronized關鍵字來確保只會生成單例
public static synchronized lhandanli getinstance()
return dl;
}}
上述**中的一次鎖住了乙個方法, 這個粒度有點大 ,改進就是只鎖住其中的new語句就ok。就是所謂的「雙重鎖」機制。
(2)餓漢式
又何為餓?餓者,飢不擇食;但凡有食,必急食之。此處同義:在載入類的時候就會建立類的單例,並儲存在類中。
詳見下方**示例:
public class ehandanli
//定義公開方法,返回已建立的單例
public static ehandanli getinstance()
}
2、雙重加鎖機制
何為雙重加鎖機制?
在懶漢式實現單例模式的**中,有使用synchronized關鍵字來同步獲取例項,保證單例的唯一性,但是上面的**在每一次執行時都要進行同步和判斷,無疑會拖慢速度,使用雙重加鎖機制正好可以解決這個問題:
public class slhandanli
public static slhandanli getinstance()}}
return dl;
}}
關於鎖內部的第二重空判斷的作用,當多個執行緒一起到達鎖位置時,進行鎖競爭,其中乙個執行緒獲取鎖,如果是第一次進入則dl為null,會進行單例物件的建立,完成後釋放鎖,其他執行緒獲取鎖後就會被空判斷攔截,直接返回已建立的單例物件。
3、類級內部類方式
餓漢式會占用較多的空間,因為其在類載入時就會完成例項化,而懶漢式又存在執行速率慢的情況,雙重加鎖機制呢?又有執行效率差的毛病,有沒有一種完美的方式可以規避這些毛病呢?
貌似有的,就是使用類級內部類結合多執行緒預設同步鎖,同時實現延遲載入和執行緒安全。
public class classinnerclassdanli
private classinnerclassdanli(){}
public static classinnerclassdanli getinstance()
}
如上**,所謂類級內部類,就是靜態內部類,這種內部類與其外部類之間並沒有從屬關係,載入外部類的時候,並不會同時載入其靜態內部類,只有在發生呼叫的時候才會進行載入,載入的時候就會建立單例例項並返回,有效實現了懶載入(延遲載入),至於同步問題,我們採用和餓漢式同樣的靜態初始化器的方式,借助jvm來實現執行緒安全。
其實使用靜態初始化器的方式會在類載入時建立類的例項,但是我們將例項的建立顯式放置在靜態內部類中,它會導致在外部類載入時不進行例項建立,這樣就能實現我們的雙重目的:延遲載入和執行緒安全。
4、使用場景
在spring中建立的bean例項預設都是單例模式存在的。日誌檔案,應用配置都是單例模式存在的。
**
java設計模式之單例模式
單位面試題目中有一道關於單例模式的題目.大多數參加筆試的同事都會寫出getinstance這個函式,但是當我問起什麼情況下需要使用單例 單例具體有什麼好處的時候 static函式也可以構建唯一例項,為什麼還需要單例.從使用單例的經驗來看,如下場景下,個人感覺應該使用單例 1.如果需要構建乙個工具類,...
java設計模式 之 單例模式
單例模式 有些類在程式執行過程中只需要儲存乙個例項,比如檔案管理類,音訊管理類,那麼我們如何實現乙個單例類呢?有以下幾點 1 定義乙個靜態變數 2 建構函式私有化 3 提供乙個public 靜態方法,獲取這個例項 4 一定要做執行緒同步 public static class singleton p...
Java設計模式之單例模式
說到單例模式 大家一定非常熟悉 這是最常見也是設計模式中相對簡單 好理解的設計模式 今天就跟大家掰一掰單例模式 單例模式確保某個類只有乙個例項 應用場景 執行緒池 快取 等物件常常被設計成單例 然而單例分兩種 1 惡漢式 2 懶漢式 我們先來看下 惡漢式 public class singleton...