一印蓖、單例概念
單例模式是一種對(duì)象創(chuàng)建模式,它用于產(chǎn)生一個(gè)對(duì)象的具體實(shí)例遵馆,它可以確保系統(tǒng)中一個(gè)類只產(chǎn)生一個(gè)實(shí)例
二鲸郊、好處
1、對(duì)應(yīng)頻繁使用的對(duì)象团搞,可以省略創(chuàng)建對(duì)象所花費(fèi)的時(shí)間严望,對(duì)于那些重量級(jí)對(duì)象而言多艇,是非陈呖郑客觀的一筆系統(tǒng)開銷。
2峻黍、由于new操作次數(shù)減少复隆,因此對(duì)系統(tǒng)內(nèi)存的使用頻率也會(huì)降低,這將減少GC壓力姆涩,縮短GC停頓時(shí)間
三挽拂、單例的六種寫法和各自的特點(diǎn)
餓漢/懶漢/懶漢線程安全/DCL/靜態(tài)內(nèi)部類/枚舉
1.餓漢
public class HungrySingleton {
//1.實(shí)例化變量是靜態(tài)的
private static HungrySingleton singleton = new HungrySingleton();
//2.構(gòu)造方法是私有的
private HungrySingleton(){
//一旦使用此方法立馬被調(diào)用
}
//獲取實(shí)例的方法是靜態(tài)的
public static HungrySingleton getHungrySingleton(){
return singleton;
}
}
缺點(diǎn):即使沒有使用這個(gè)類都會(huì)被初始化,如果初始化內(nèi)容比較多的話骨饿,對(duì)性能的影響是很大的
無法對(duì)instance實(shí)例做延遲加載
2.懶漢模式
public class LazySingleton {
public static? LazySingleton singleton;
//構(gòu)造方法是私有的
private LazySingleton(){}
public static LazySingleton getSingleton(){
if (singleton==null){
//第一次創(chuàng)建時(shí)會(huì)被初始化
singleton = new LazySingleton();
}
return singleton;
}
}
缺點(diǎn):(并非同步)多線程的并非這樣的實(shí)現(xiàn)是無法保證實(shí)例是唯一的
3.懶漢線程安全模式
public class LazySafeSingleton {
public static LazySafeSingleton safeSingleton;
private LazySafeSingleton(){}
//方法中聲明synchronized關(guān)鍵字(方法一)
public synchronized static LazySafeSingleton getSafeSingleton(){
if (safeSingleton==null){
safeSingleton = new LazySafeSingleton();
}
return? safeSingleton;
}
//同步代碼塊的實(shí)現(xiàn)(方法二)
public static? LazySafeSingleton getInstance(){
synchronized (LazySafeSingleton.class){
if (safeSingleton==null){//
safeSingleton = new LazySafeSingleton();
}
}
return safeSingleton;
}
}
缺點(diǎn):性能(synchronized關(guān)鍵字)上的缺點(diǎn)亏栈,每次只有一個(gè)線程讀取實(shí)例
4.DCL(double check lock)雙重檢查鎖設(shè)計(jì)模式
public class DCLSingleton {
private static? volatile DCLSingleton? singleton;
private DCLSingleton(){}
public static DCLSingleton getInstance(){
//避免不必要的同步
if (singleton==null){
//同步
synchronized (DCLSingleton.class){
//在第一次調(diào)用時(shí)初始化
if (singleton==null){
singleton = new DCLSingleton();
}
}
}
return singleton;
}
}
//可能會(huì)有多個(gè)線程一起進(jìn)入同步代碼塊外的情況,如果不檢驗(yàn)的話就會(huì)生成多個(gè)實(shí)例宏赘,就成了
懶漢模式中的缺點(diǎn)
//缺點(diǎn):JVM的即時(shí)編譯器中存在指令重排序的優(yōu)化(volatile)優(yōu)化
5.靜態(tài)內(nèi)部類單例設(shè)計(jì)模式
public class StaticSingleton {
private StaticSingleton(){}
public static StaticSingleton getInStance(){
return Singler.singleton;
}
//靜態(tài)內(nèi)部類
private static class Singler{
private static? final StaticSingleton singleton = new StaticSingleton();
}
}
//優(yōu)點(diǎn):jvm本身機(jī)制保證了線程安全/沒有性能缺陷
原因:static/final(初始化之后無法被修改)
6.枚舉單例設(shè)計(jì)模式(java5之后)
public enum? EnumSingleton {
//定義一個(gè)枚舉的元素绒北,它是singleton的實(shí)例
INSTANCE;
public void doSomething(){
}
}
優(yōu)點(diǎn):寫法簡(jiǎn)單/線程安全