003.單例模式

接觸學(xué)生的時(shí)候,總是在說設(shè)計(jì)模式很重要,至少應(yīng)該知道幾種設(shè)計(jì)模式?
但是,也是給大家簡簡單單的介紹了幾種!
設(shè)計(jì)模式就是讓自己的代碼更加完善,更加健壯

第一種方案:懶漢式

懶漢式的類的實(shí)例創(chuàng)建是在getInstance方法中,懶漢式是典型的時(shí)間換空間,也就是每次獲取實(shí)例都會(huì)進(jìn)行判斷,看是否需要?jiǎng)?chuàng)建實(shí)例,浪費(fèi)判斷的時(shí)間。
當(dāng)然,如果一直沒人使用的話,那就不會(huì)創(chuàng)建實(shí)例,則節(jié)約內(nèi)存空間

package 單例模式;

/**
 * 懶漢式
 * @author 胖先森
 *
 */
public class Singleton1 {
    private static Singleton1 uniqueInstance = null;
    
    private Singleton1(){}
    
    public static synchronized Singleton1 getInstance(){
        if(uniqueInstance == null){
            uniqueInstance = new Singleton1();
        }
        return uniqueInstance;
    }
    
}

這種懶漢式不加同步,所以是線程不安全的,可以加上synchornized使得線程安全
加入同步之后代碼為: public static synchronized Singleton getInstance(){}

但是這樣會(huì)降低整個(gè)訪問的速度,而且每次都要判斷,可以使用“雙重檢查加鎖”使得即線程安全,又能使性能不受到很大的影響。

“雙重檢查加鎖”是指并不是每次進(jìn)入getInstance方法都需要同步,而是先不同步,進(jìn)入方法過后,先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊,這是第一重檢查,進(jìn)入同步塊過后,再次檢查實(shí)例是否存在,不過不存在,就在同步的情況下創(chuàng)建一個(gè)實(shí)例,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步的情況下進(jìn)行判斷所浪費(fèi)的時(shí)間,實(shí)現(xiàn)如下:

package 單例模式;

/**
 * 雙重加鎖懶漢式
 * @author Administrator
 *
 */
public class Singleton3 {
    
    private volatile static Singleton3 instance = null;
    
    private Singleton3(){}
    
    public static Singleton3 getInstance(){
        if(instance == null){
            synchronized (Singleton3.class) {
                if(instance == null){
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}

第二種方案:餓漢式

在課堂就是講了這種方式,我們?cè)賮砜纯?br> 餓漢式是典型的空間換時(shí)間,當(dāng)類加載的時(shí)候就會(huì)創(chuàng)建類實(shí)例,不管你用不用,先創(chuàng)建出來,然后每次電泳的時(shí)候,就不需要再判斷了,節(jié)省了運(yùn)行時(shí)間,餓漢式是線程安全的

package 單例模式;

/**
 * 餓漢式
 * @author 胖先森
 *
 */

public class Singleton2 {
    
    private static Singleton2 uniqueInstance= new Singleton2();
    
    private Singleton2(){}
    
    public static Singleton2 getInstance(){
        return uniqueInstance;
    }
}

內(nèi)部類實(shí)現(xiàn)方式

上面兩種方案都有一定的缺陷,那么有沒有一種方法既能夠?qū)崿F(xiàn)延遲加載,又能夠?qū)崿F(xiàn)線程安全呢?

要想實(shí)現(xiàn)線程安全,可以采用靜態(tài)初始化器的方式,它可以由JVM來保證線程的安全性,例如前面的餓漢式,但這樣一來,會(huì)浪費(fèi)一定的空間。

如果有一種方法能夠讓類裝載的時(shí)候不去初始化對(duì)象,不就解決問題了嗎?一種可行的方法就是采用內(nèi)部類,在這個(gè)內(nèi)部類里面去創(chuàng)建對(duì)象實(shí)例,這樣一來,只要不實(shí)用到這個(gè)類級(jí)內(nèi)部類,就不會(huì)創(chuàng)建對(duì)象實(shí)例,從而同時(shí)實(shí)現(xiàn)延遲加載和線程安全。

package 單例模式;


/**
 * 使用內(nèi)部靜態(tài)類,線程安全且高效
 * @author 胖先森
 *
 */
public class Singleton4 {
    
    private static class SingletonHolder{
        private static Singleton4 instance = new Singleton4();
    }
    
    private Singleton4(){
        
    }
    public static Singleton4 getInstance(){
        return SingletonHolder.instance;
    }
}

參考內(nèi)容:單例模式的七種寫法

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

相關(guān)閱讀更多精彩內(nèi)容

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