單例模式
一.單例模式介紹
單例模式是Java二十三種設(shè)計(jì)模式中的一種家破,也是一種比較常用的設(shè)計(jì)模式族沃。其作用是保證該類只能擁有一個(gè)實(shí)例對(duì)象。
二.實(shí)現(xiàn)步驟
1.私有化該類的構(gòu)造方法,讓其他類無法通過構(gòu)造器創(chuàng)建該類的實(shí)例拟蜻。
2.提供可以獲取到該類實(shí)例的靜態(tài)方法篓冲,讓其他類通過該方法獲取到該類的實(shí)例龄广。
三.寫法介紹
1.餓漢式
1.1 介紹
因?yàn)樵擃惖膶?shí)例是在類加載的時(shí)候就創(chuàng)建出來的蒲讯,并不是在使用的時(shí)候。就像被餓了很久的人見到吃的刚操,不管三七二十一闸翅,先填飽肚子再說。所以把這種寫法叫做餓漢式菊霜。
1.2 Java代碼
public class Test{
//本類持有本類的引用
private static Test mInstance = new Test();
//將構(gòu)造方法私有化
private Test(){
}
//提供一個(gè)對(duì)外的方法獲取本類的引用
public static Test getInstance(){
return mInstance;
}
}
1.3 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):寫法簡單坚冀,線程安全,避免了線程同步的問題鉴逞。
缺點(diǎn):因?yàn)閷?shí)例是在類加載的時(shí)候初始化记某,所以它的生命周期是和類相同。即使它從未被用到构捡,也不會(huì)被系統(tǒng)回收液南,造成內(nèi)存的浪費(fèi)。
可以但是不推薦使用餓漢式勾徽。
2.懶漢式(基本寫法)
2.1 介紹
該寫法是只有在使用的時(shí)候才進(jìn)行實(shí)例創(chuàng)建滑凉。就像一個(gè)懶漢只有當(dāng)餓了的時(shí)候才去吃飯。
2.2 Java代碼
public class Test{
private static Test mInstance;
private Test(){
}
public static Test getInstance(){
if(null = mInstance){
mInstance = new Test();
}
return mInstance;
}
}
2.3 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):當(dāng)使用的時(shí)候才進(jìn)行實(shí)例化喘帚,不會(huì)造成內(nèi)存的浪費(fèi)畅姊。起到了Lazy Loading的效果。
缺點(diǎn):在單線程該寫法沒有問題吹由。但是在多線程情況下若未,是線程不安全的。
不推薦使用該寫法倾鲫。
3.懶漢式(同步方法)
3.1 介紹
為了解決懶漢式的線程不安全問題粗合,把getInstance()方法進(jìn)行線程同步。
3.2 Java代碼
public class Test{
private static Test mInstance;
private Test(){
}
public static synchronized Test getInstance(){
if(null == mInstance){
mInstance = new Test();
}
return mInstance;
}
}
*3.3 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):解決了線程安全問題乌昔。
缺點(diǎn):同步效率低隙疚。每次調(diào)用getInstance方法時(shí)都要進(jìn)行同步。但實(shí)際上只有當(dāng)mInstance == null時(shí)才有同步的必要磕道,不為null時(shí)直接return就OK了甚淡。
不推薦使用。
4.懶漢式(同步代碼塊)
4.1 介紹
為了解決同步方法效率低而產(chǎn)生的寫法。
4.2 代碼
public class Test{
private static Test mInstance;
private Test(){
}
public static Test getInstance(){
if(null == mInstance){
synchronized(Test.class){
mInstance = new Test();
}
}
return mInstance;
}
}
4.3 優(yōu)缺點(diǎn)
和傳統(tǒng)的懶漢式基本沒區(qū)別贯卦。都是線程不安全。
不推薦使用焙贷。
5.懶漢式(雙重檢查)
5.1 介紹
在同步方法的基礎(chǔ)上再進(jìn)行改良的撵割。
5.2
public class Test{
private static volatile Test mInstance;
private Test(){
}
public static Test getInstance(){
if(null == mInstance){
synchronized(Test.class){
if(null == mInstance){
Test = new Test();
}
}
}
return mInstance;
}
}
5.3 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):這種懶漢式的寫法用到了Double-Check。進(jìn)行了兩次非空判斷辙芍,保證了線程安全啡彬,并且只實(shí)例化的一次代碼。該寫法線程安全故硅,延遲加載庶灿,效率高。
缺點(diǎn):無吃衅。
推薦使用往踢。
6.靜態(tài)內(nèi)部類
6.1 介紹
靜態(tài)內(nèi)部類跟餓漢式方式采用的機(jī)制類似,但又不同徘层。兩者都是采用了類裝載的機(jī)制來保證初始化實(shí)例時(shí)只有一個(gè)線程峻呕。不同的是餓漢式在類被裝載時(shí)被實(shí)例化,沒有Lazy Loading的作用趣效。而靜態(tài)內(nèi)部類方式在類被裝載時(shí)并不會(huì)實(shí)例化瘦癌,而是在需要實(shí)例化時(shí),才會(huì)調(diào)用跷敬。
6.2 代碼
public class Test{
private Test(){
}
private static class SingletonInstance{
private static final Test INSTANCE = new Test();
}
public static Test getInstance(){
return SingletonInstance.INSTANCE;
}
}
6.3 優(yōu)缺點(diǎn)
優(yōu)點(diǎn):利用類的靜態(tài)屬性保證唯一性讯私,JVM保證線程安全,延遲加載西傀,效率高斤寇。
推薦使用。
7.枚舉
7.1 代碼
public enum Test{
INSTANCE;
public void whateverMethod(){
}
}
本文章參考了CSDN的博客池凄,這是去往該作者的 鏈接.