欧美free性护士vide0shd,老熟女,一区二区三区,久久久久夜夜夜精品国产,久久久久久综合网天天,欧美成人护士h版

首頁綜合 正文
目錄

柚子快報激活碼778899分享:JavaEE--單例模式

柚子快報激活碼778899分享:JavaEE--單例模式

http://yzkb.51969.com/

1.設(shè)計模式

設(shè)計模式是在軟件開發(fā)中解決常見問題的最佳實踐或方案。使用設(shè)計模式可以實現(xiàn)可重用代碼,幫助我們創(chuàng)建更靈活、可維護(hù)和可擴(kuò)展的代碼。而我們要介紹的單例模式就是設(shè)計模式中比較經(jīng)典的一種模式。

2.單例模式

單例模式就是單個實例,在整個進(jìn)程中的某個類,有且只有一個對象,這樣的對象就被稱為“單例”,那么如何保證這個類只有一個實例呢?這就需要編譯器來幫我們做一個強(qiáng)制的檢查,通過一些編程上的技巧,使編譯器可以自動發(fā)現(xiàn)代碼中是否含有多個實例,并且在嘗試創(chuàng)建多個實例時,直接編譯報錯,從根本上保證對象是唯一實例,這樣的代碼就稱為單例模式。

單例模式的實現(xiàn)方式有很多,我們主要介紹“餓漢模式”與“懶漢模式”

?2.1 餓漢模式

唯一實例的創(chuàng)建時間非常早,在類加載的同時就創(chuàng)建實例(就像一個餓了很久的人,看到吃的就迫不及待地開始吃起來)

public class Singleton {

private static Singleton instance=new Singleton();//static成員在類加載時初始化

public static Singleton getInstance(){

return instance;

}

private Singleton(){

//類外的代碼在嘗試new的時候,需要調(diào)用構(gòu)造方法,由于構(gòu)造方法是私有的,無法調(diào)用,就會編譯出錯

//通過用private修飾構(gòu)造方法,有效地禁止了外部代碼創(chuàng)建該類的實例

}

}

class Hungry{

Singleton singleton1 = Singleton.getInstance();

Singleton singleton2 = Singleton.getInstance();

}

2.2 懶漢模式

不是在程序啟動的時候創(chuàng)建實例,而是在第一次使用的時候才去創(chuàng)建實例

public class Singleton1 {

private static Singleton1 instance = null;

public static Singleton1 getInstance() {//什么時候調(diào)用,什么時候創(chuàng)建

if(instance == null) {

instance = new Singleton1();

}

return instance;

}

private Singleton1(){

}

}

class Lazy{

Singleton1 singleton1 = Singleton1.getInstance();

Singleton1 singleton2 = Singleton1.getInstance();

}

3.是否線程安全

在單線程環(huán)境下,上述兩種模式的代碼都夠正常執(zhí)行,但是當(dāng)處于多線程環(huán)境中,有多個線程調(diào)用getInstance方法時,這兩種模式會不會出現(xiàn)線程安全問題呢?

3.1 餓漢模式(線程安全)

在餓漢模式中,實例創(chuàng)建的時間是在java進(jìn)程啟動時(比main線程被調(diào)用還早),后續(xù)在代碼中創(chuàng)建線程一定比實例的創(chuàng)建更加晚,所以當(dāng)后續(xù)線程在執(zhí)行g(shù)etInstance方法時,實例早就已經(jīng)創(chuàng)建完畢,而getInstance方法只是去讀取了這個創(chuàng)建好的實例的值,相當(dāng)于多個線程去讀取同一個變量,不存在線程安全問題

3.2 懶漢模式(線程不安全)及改進(jìn)

在懶漢模式的getInstance方法中,存在賦值(修改)操作,在多線程中就可能會線程安全問題,我們來舉個例子

由于線程是隨機(jī)調(diào)度,搶占式執(zhí)行的,當(dāng)t1線程執(zhí)行到任何一個指令,t2線程都有可能搶占到cpu上繼續(xù)執(zhí)行,圖中只是其中一種執(zhí)行順序,還會有其他執(zhí)行順序的可能。按照圖中的執(zhí)行順序來看,t1線程和t2線程都分別創(chuàng)建了一個實例(都進(jìn)行了new操作),當(dāng)實例對象的內(nèi)存數(shù)據(jù)較大時,多加載一次內(nèi)存數(shù)據(jù)會有很大的時間開銷

那么如何改進(jìn)代碼呢?

1.使用synchronized關(guān)鍵字,將if和new打包成一個原子操作,

2.由于只有第一次調(diào)用getInstance方法才會存在線程安全問題,一旦實例創(chuàng)建完畢,在后續(xù)調(diào)用中進(jìn)行的只是讀操作,不存在線程安全問題,這時進(jìn)行加鎖,就有點多余了,并且加鎖操作本身也有一定開銷(可能會使線程阻塞),所以需要添加一個if語句判斷是否需要加鎖

3.在兩個if語句之間,synchronized會使線程阻塞,在阻塞過程中其他線程可能會修改instance的值,由于內(nèi)存可見性問題,該線程可能沒有感知到,所以需要給instance變量添加volatile關(guān)鍵字

4.可能會出現(xiàn)指令重排序問題,也需要給instance變量添加volatile關(guān)鍵字

public class Singleton1 {

private static volatile Singleton1 instance = null;

private static Object locker = new Object();

public static Singleton1 getInstance() {

if(instance == null) {//判定是否要加鎖

//實例化之前需要加鎖

// 實例化之后,線程已經(jīng)安全,無需加鎖

synchronized (locker) {

if (instance == null) {

instance = new Singleton1();

}

}

}

return instance;

}

private Singleton1(){

}

}

class Lazy{

Singleton1 singleton1 = Singleton1.getInstance();

Singleton1 singleton2 = Singleton1.getInstance();

}

柚子快報激活碼778899分享:JavaEE--單例模式

http://yzkb.51969.com/

相關(guān)鏈接

評論可見,查看隱藏內(nèi)容

本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。

轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。

本文鏈接:http://m.gantiao.com.cn/post/18841369.html

發(fā)布評論

您暫未設(shè)置收款碼

請在主題配置——文章設(shè)置里上傳

掃描二維碼手機(jī)訪問

文章目錄