java設(shè)計(jì)優(yōu)化之單例模式
單例模式是一種對(duì)象創(chuàng)建模式,確保系統(tǒng)中一個(gè)類只有一個(gè)實(shí)例。
在java語言中,這樣做有兩大好處:
1.對(duì)于頻繁使用的對(duì)象,可以省略創(chuàng)建對(duì)象所話費(fèi)的時(shí)間;
2.由于new操作的次數(shù)減少,對(duì)于系統(tǒng)內(nèi)存的使用頻率降低,這樣減少GC的壓力,縮短GC停頓的時(shí)間。
單例模式細(xì)分:
1.
public class Singleton{
private Singleton(){
System.out.println("Singleton.Singleton()");
}
private static Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
}
注意:首先單例類必須有一個(gè)private訪問級(jí)別的構(gòu)造函數(shù),確保單例不會(huì)被系統(tǒng)其他代碼實(shí)例化;其次,singleton成員變量和getInstance()方法必須是static的。
這個(gè)單例類創(chuàng)建十分簡(jiǎn)單,而且非??煽?。唯一的缺點(diǎn)是無法對(duì)singleton做延遲加載,例如由于單例創(chuàng)建過程很慢,由于成員變量定義為static,在jvm加載單例類時(shí),單例對(duì)象也會(huì)被創(chuàng)建,那么在任何用到單例類的地方都會(huì)創(chuàng)建單例對(duì)象,不管單例對(duì)象是否被用到。例如:
public class Singleton{
private Singleton(){
System.out.println("Singleton.Singleton()");
}
private static Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
public static void createString(){
System.out.println("Singleton.createString()");
}
}
2.為了提高相關(guān)函數(shù)的調(diào)用速度,就需要引入懶加載機(jī)制。
package com.luchao.singtonle;
public class LazySingleton {
private LazySingleton() {
System.out.println("LazySingleton.LazySingleton()");
}
private static LazySingleton lazyInstance = null;
public synchronized static LazySingleton getInstance(){
if(lazyInstance==null)
lazyInstance = new LazySingleton();
return lazyInstance;
}
}
對(duì)于靜態(tài)變量singleton初始化賦值為null,確保系統(tǒng)啟動(dòng)時(shí)沒有額外的負(fù)荷。在getInstance()方法中,判斷當(dāng)前實(shí)例十分已經(jīng)存在,如果存在則返回,如果不存在,再建單例。getInstance()必須為同步方法,因?yàn)樵诙嗑€程環(huán)境下,當(dāng)線程1正在建單例,未完成賦值前,線程2可能判斷instance為null,故線程2將啟動(dòng)建立新建單例的程序,導(dǎo)致多個(gè)單例被創(chuàng)建。
上面實(shí)例單例實(shí)現(xiàn),雖然實(shí)現(xiàn)了延遲加載,但是引入了同步方法,在多線程環(huán)境下,耗時(shí)遠(yuǎn)大于第一個(gè)單例程序。
3.單例模式使用內(nèi)部類來維護(hù)單例的創(chuàng)建
public class StaticSingleton {
private StaticSingleton() {
System.out.println("StaticSingleton.StaticSingleton()");
}
private static class SingletonHolder{
private static StaticSingleton ataticSingleton = new StaticSingleton();
}
public static StaticSingleton getInstance(){
return SingletonHolder.ataticSingleton;
}
}
StaticSingleton被加載時(shí),內(nèi)部類不會(huì)被實(shí)例化,確保StaticSingleton類被載入jvm時(shí),不會(huì)被初始化單例類,而當(dāng)getInstance()方法被調(diào)用時(shí),才加載SingletonHolder,從而初始化instance。同時(shí)用于實(shí)例的建立在類加載時(shí)完成,故天生對(duì)線程友好。
使用內(nèi)部類完成單利模式,既可以做到延遲加載,也不用使用同步關(guān)鍵字,是一種比較完善的做法。
以上就是本文的全部?jī)?nèi)容希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
SpringBoot集成E-mail發(fā)送各種類型郵件
這篇文章主要為大家詳細(xì)介紹了SpringBoot集成E-mail發(fā)送各種類型郵件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
解析spring-boot-starter-parent簡(jiǎn)介
本文通過代碼的形式給大家介紹了spring-boot-starter-parent的基礎(chǔ)知識(shí),需要的朋友可以參考下2018-09-09
Java中使用數(shù)組實(shí)現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)實(shí)例
這篇文章主要介紹了Java中使用數(shù)組實(shí)現(xiàn)棧數(shù)據(jù)結(jié)構(gòu)實(shí)例,本文先是講解了實(shí)現(xiàn)棧至少應(yīng)該包括以下幾個(gè)方法等知識(shí),然后給出代碼實(shí)例,需要的朋友可以參考下2015-01-01
JAVA實(shí)現(xiàn)監(jiān)測(cè)tomcat是否宕機(jī)及控制重啟的方法
這篇文章主要介紹了JAVA實(shí)現(xiàn)監(jiān)測(cè)tomcat是否宕機(jī)及控制重啟的方法,可實(shí)現(xiàn)有效的檢測(cè)及控制tomcat服務(wù)器運(yùn)行,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
Java使用POI將多個(gè)Sheet合并為一個(gè)Sheet
這篇文章主要為大家詳細(xì)介紹了Java使用POI將多個(gè)Sheet合并為一個(gè)Sheet,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04

