日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

java23种设计模式+单例_Java23种设计模式之单例模式

發(fā)布時(shí)間:2025/3/19 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java23种设计模式+单例_Java23种设计模式之单例模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、單例模式簡(jiǎn)介

單例模式是Java設(shè)計(jì)模式中常見(jiàn)的一種模式。主要分為懶漢式單例、餓漢式單例、登記式單例;

單例模式的特點(diǎn): ?1、單例類只能有一個(gè)實(shí)例; ?2、單例類必須自己創(chuàng)建自己的唯一的實(shí)例; 3、單例類必須給所有其他對(duì)象提供這一實(shí)例;

二、餓漢式單例

public classSingleTonModel {privateSingleTonModel(){}private static final SingleTonModel singt=newSingleTonModel();public staticSingleTonModel getInstance(){returnsingt;

}

}

餓漢式在類創(chuàng)建的同時(shí)就已經(jīng)創(chuàng)建好一個(gè)靜態(tài)的對(duì)象供系統(tǒng)使用,以后不再改變,所以天生是線程安全的。

三、懶漢式單例

簡(jiǎn)單的例子:

public classSingleTonModel {privateSingleTonModel(){}private static SingleTonModel singt=null;public staticSingleTonModel getInstance(){if(singt==null){

singt=newSingleTonModel();

}returnsingt;

}

}

Singleton通過(guò)將構(gòu)造方法限定為private避免了類在外部被實(shí)例化,在同一個(gè)虛擬機(jī)范圍內(nèi),Singleton的唯一實(shí)例只能通過(guò)getInstance()方法訪問(wèn)。

(事實(shí)上,通過(guò)Java反射機(jī)制是能夠?qū)嵗瘶?gòu)造方法為private的類的,那基本上會(huì)使所有的Java單例實(shí)現(xiàn)失效。此問(wèn)題在此處不做討論,姑且掩耳盜鈴地認(rèn)為反射機(jī)制不存在。)

但是以上懶漢式單例的實(shí)現(xiàn)沒(méi)有考慮線程安全問(wèn)題,它是線程不安全的,并發(fā)環(huán)境下很可能出現(xiàn)多個(gè)Singleton實(shí)例,要實(shí)現(xiàn)線程安全,有以下三種方式,都是對(duì)getInstance這個(gè)方法改造,保證了懶漢式單例的線程安全:(課外知識(shí)可以了解線程安全)

改造一:在靜態(tài)方法上添加關(guān)鍵詞:synchronized,進(jìn)行同步

public classSingleTonModel {privateSingleTonModel(){}private static SingleTonModel singt=null;public staticsynchronizedSingleTonModel getInstance(){if(singt==null){

singt=newSingleTonModel();

}returnsingt;

}

}

雖然通過(guò)同步保障了線程安全,但是每次都要同步,會(huì)影響性能,畢竟99%的情況下是不需要同步的。

改造二:在判斷不存在實(shí)例時(shí)才進(jìn)行同步

public classSingleTonModel {privateSingleTonModel(){}private static SingleTonModel singt=null;public staticSingleTonModel getInstance(){if(singt==null){

synchronized(SingleTonModel.class){if(singt==null){

singt=newSingleTonModel();

}

}

}returnsingt;

}

}

在getInstance中做了兩次null檢查,確保了只有第一次調(diào)用單例的時(shí)候才會(huì)做同步,這樣也是線程安全的,同時(shí)避免了每次都同步的性能損耗。

改造三:添加內(nèi)部靜態(tài)類

public classSingleTonModel {privateSingleTonModel(){}private static classlanSingleton{private static final SingleTonModel singt=newSingleTonModel();

}public staticfinal SingleTonModel getInstance(){returnlanSingleton.singt;

}

}

利用了classloader的機(jī)制來(lái)保證初始化instance時(shí)只有一個(gè)線程,所以也是線程安全的,同時(shí)沒(méi)有性能損耗,所以一般我傾向于使用這一種。

四、登記式單例(很少用)

/類似Spring里面的方法,將類名注冊(cè),下次從里面直接獲取。public classSingleton3 {private static Map map = new HashMap();static{

Singleton3 single= newSingleton3();

map.put(single.getClass().getName(), single);

}//保護(hù)的默認(rèn)構(gòu)造子

protectedSingleton3(){}//靜態(tài)工廠方法,返還此類惟一的實(shí)例

public staticSingleton3 getInstance(String name) {if(name == null) {

name= Singleton3.class.getName();

System.out.println("name == null"+"--->name="+name);

}if(map.get(name) == null) {try{

map.put(name, (Singleton3) Class.forName(name).newInstance());

}catch(InstantiationException e) {

e.printStackTrace();

}catch(IllegalAccessException e) {

e.printStackTrace();

}catch(ClassNotFoundException e) {

e.printStackTrace();

}

}return map.get(name);

}//一個(gè)示意性的商業(yè)方法

publicString about() {return "Hello, I am RegSingleton.";

}public static voidmain(String[] args) {

Singleton3 single3= Singleton3.getInstance(null);

System.out.println(single3.about());

}

}

登記式單例實(shí)際上維護(hù)了一組單例類的實(shí)例,將這些實(shí)例存放在一個(gè)Map(登記薄)中,對(duì)于已經(jīng)登記過(guò)的實(shí)例,則從Map直接返回,對(duì)于沒(méi)有登記的,則先登記,然后返回。

課外小知識(shí):

1、什么是線程安全

如果你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,就是線程安全的。

或者說(shuō):一個(gè)類或者程序所提供的接口對(duì)于線程來(lái)說(shuō)是原子操作,或者多個(gè)線程之間的切換不會(huì)導(dǎo)致該接口的執(zhí)行結(jié)果存在二義性,也就是說(shuō)我們不用考慮同步的問(wèn)題,那就是線程安全的。

總結(jié)

以上是生活随笔為你收集整理的java23种设计模式+单例_Java23种设计模式之单例模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。