更新時間:2022-09-19 11:04:11 來源:動力節(jié)點 瀏覽1470次
Java單例模式可以說是設(shè)計模式里面最好理解的一個模式了,它的意思就是一個類只創(chuàng)建一個對象,所有的引用都只向該對象去操作。
單例模式滿足的要求:
1.構(gòu)造函數(shù)私有化
2.類的內(nèi)部創(chuàng)建實例
3.提供靜態(tài)的唯一獲取實例的方法
public class Singleton {
private static Singleton singleton=new Singleton(); //內(nèi)部創(chuàng)建實例
private Integer data=0; //成員變量
private Singleton(){} //構(gòu)造函數(shù)私有化
//本身線程安全
public static Singleton getTarget(){
return singleton;
}
}
public class Singleton {
private static Singleton singleton=null; //內(nèi)部創(chuàng)建實例
private Integer data=0; //成員變量
private Singleton(){} //構(gòu)造函數(shù)私有化
//使用同步方法保證線程安全
public static synchronized Singleton getTarget(){
if (singleton==null) {
singleton = new Singleton();
}
return singleton;
}
}
public class Singleton {
private volatile static Singleton singleton=null; //內(nèi)部創(chuàng)建實例,并使用volatile修飾保證其可見性
private Integer data=0; //成員變量
//構(gòu)造函數(shù)私有化
private Singleton(){}
//對外提供獲取實例方法,并且通關(guān)雙重判空,為什么要使用雙重判空而不是單重?
//1.外判內(nèi)不判:如果同時兩個線程先判空進入方法內(nèi)后,一個線程拿到鎖進去
//創(chuàng)建對象,另一個線程再拿到鎖進去又創(chuàng)建對象
//2.內(nèi)判外不判:外判可以先判是否有對象,不需要進去同步代碼塊提高效率
//同步代碼塊加鎖的方式保證線程安全,只創(chuàng)建出一個實例,對比懶漢式效率更高
public static Singleton getTarget(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
public class Singleton {
private Integer data=0; //成員變量
private Singleton(){} //構(gòu)造函數(shù)私有化
//靜態(tài)內(nèi)部類
private static class Target{
private static final Singleton singleton = new Singleton();//內(nèi)部類創(chuàng)建實例
}
//當任何一個線程第一次調(diào)用getTarget()時,都會使Target被
//加載和被初始化,此時靜態(tài)初始化器將執(zhí)行Singleton的初始化操作。
// (被調(diào)用時才進行初始化!)初始化靜態(tài)數(shù)據(jù)時,Java提供了的線程安全性保證。
public static final Singleton getTarget(){
return Target.singleton;
}
}
public enum Singleton {
JAVA_Singleton,
}
好處:我們?yōu)槭裁匆褂脝卫J侥?它有什么好處?
1.第一個單例模式可以讓我們只創(chuàng)建一個對象從而避免了頻繁創(chuàng)建對象導(dǎo)致的內(nèi)存消耗和垃圾回收,一個對象可以搞定的事何樂而不為,除非是特殊情況(Struts2是多例的)。
2.Servlet是單例模式,我們只需要創(chuàng)建一個Servlet,然后接收請求并處理,這樣我們可以很省內(nèi)存。spring的bean默認也是單例模式,springMVC是單例模式,所以我們可以發(fā)現(xiàn)我們的service層,dao層,web層都是使用單例模式,單例無處不在。線程的線程池的設(shè)計一般也是采用單例模式,這是由于線程池要方便對池中的線程進行控制。mysql,redis等的連接對象使用單例模式例模式的另外一個好處是可以讓我們操作同一個共享變量來保證同步。網(wǎng)站的計數(shù)器,一般也是采用單例模式實現(xiàn),來保證其同步。
以上就是關(guān)于“單例模式的應(yīng)用場景介紹”,大家如果想了解更多相關(guān)知識,不妨來關(guān)注一下動力節(jié)點的Java設(shè)計模式,里面還有更豐富的知識等著大家去學(xué)習,希望對大家能夠有所幫助哦。