Java設(shè)計模式之單例模式(看完不會你打我)

零、什么是單例模式?

單例,單例,顧名思義這個類從頭至尾只有一個實(shí)例。

單例模式具備以下三個特點(diǎn):

  • 私有化的構(gòu)造函數(shù)

  • 私有的靜態(tài)的全局變量

  • 公有的靜態(tài)的方法

常用的三種單例模式:

  • 懶漢模式(線程不安全)

  • 餓漢模式(線程安全,資源利用率不高)

  • 雙重校驗(yàn)鎖模式(線程安全,資源利用率高)

一、懶漢模式(線程不安全)

類加載的時候,“懶”的去創(chuàng)建一個實(shí)例;

當(dāng)?shù)谝淮伪皇褂玫臅r候我才給你創(chuàng)建實(shí)例,延遲加載

示例代碼如下:

/**
 *  懶漢式
 *  線程不安全,延遲初始化
 * @author :Negen
 * @Date :Created in 15:25 2020/5/23
 * @Description:
 * @Modified By:
 * @Version: 1.0
 */
public class SingletonLazy {
    //私有的靜態(tài)的全局變量
    private static SingletonLazy instanse;
    //私有化的構(gòu)造函數(shù)
    private SingletonLazy(){};
    //公有的靜態(tài)的方法
    public static SingletonLazy getInstance(){
        if (null == instanse){ //線程不安全觸發(fā)點(diǎn)
            instanse = new SingletonLazy();
        }
        return instanse;
    }
}

二、餓漢模式(線程安全)

類加載的時候就創(chuàng)建一個實(shí)例;

創(chuàng)建的實(shí)例如果一直沒有使用的話,就會造成資源浪費(fèi);

實(shí)例代碼如下:

/**
 *  餓漢模式
 *  線程安全,常用
 *  一開始就創(chuàng)建了實(shí)例,如果一直沒用,就是產(chǎn)生的垃圾
 * @author :Negen
 * @Date :Created in 15:30 2020/5/23
 * @Description:
 * @Modified By:
 * @Version: 1.0
 */
public class SingletonHungary {
    private static SingletonHungary instance = new SingletonHungary();
    private SingletonHungary(){};
    public static SingletonHungary getInstance(){
        return instance;
    }
}

三、雙重校驗(yàn)鎖模式(線程安全)

對實(shí)例進(jìn)程兩次是否為空的檢查;

第一次檢查是為了防止不必要的鎖;

第二次就是例行檢查;

示例代碼如下:

/**
 *  雙重檢查模式
 *
 *  第一次:避免不必要的上鎖
 *  第二次:例行檢查
 * @author :Negen
 * @Date :Created in 16:28 2020/5/23
 * @Description:
 * @Modified By:
 * @Version: 1.0
 */
public class SingletonDoubleCheckLock {
    private volatile static SingletonDoubleCheckLock instance;
    private SingletonDoubleCheckLock(){};
    public static SingletonDoubleCheckLock getInstance(){
        if (null == instance){
            synchronized (SingletonDoubleCheckLock.class){
                if (null == instance){
                    instance = new SingletonDoubleCheckLock();
                }
            }
        }
        return instance;
    }
}

四、線程不安全體現(xiàn)在哪兒?

如果有兩個線程同時進(jìn)入 if(instance == null)階段,那么它們都會進(jìn)入創(chuàng)建實(shí)例的階段,從而導(dǎo)致創(chuàng)建多個不同的實(shí)例。

下面用多線程模擬了三種模式創(chuàng)建實(shí)例的結(jié)果

1、懶漢模式

示例代碼:

public class TestLazy implements Runnable{
    public static void main(String[] args) {
        for (int i = 0; i<10; i++){
            TestLazy test = new TestLazy();
            new Thread(test).start();
        }
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "----" + SingletonLazy.getInstance().toString());
    }
}

打印結(jié)果:

懶漢模式結(jié)果.png

十個線程中出現(xiàn)了三個不同的地址,說明“懶漢模式”線程不安全

2、餓漢模式

示例代碼:

public class TestHungary implements Runnable{
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++){
            TestHungary test = new TestHungary();
            new Thread(test).start();
        }
    }
    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "----" + SingletonHungary.getInstance().toString());
    }
}

打印結(jié)果:

[圖片上傳失敗...(image-34b196-1590225907614)]

十個線程中出現(xiàn)的都是相同的地址,說明“餓漢模式”線程安全

3、雙重校驗(yàn)鎖模式

示例代碼:

public class TestDoubleCheckLock implements Runnable{
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++){
            TestDoubleCheckLock testDoubleCheckLock = new TestDoubleCheckLock();
            new Thread(testDoubleCheckLock).start();

        }
    }

    @Override
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + "----" + SingletonDoubleCheckLock.getInstance().toString());
    }
}

打印結(jié)果:

[圖片上傳失敗...(image-96367b-1590225907614)]

十個線程中出現(xiàn)的都是相同的地址,說明“雙重校驗(yàn)鎖模式”線程安全

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容