單例模式實現的3種方式,推薦

以下爲單例模式實現的3種常用方式。

(1)餓漢模式 

public class Hungry {
    private Hungry() { }//單例模式都要注意隱藏構造器
    private  static Hungry singleTon = new Hungry();

    public static Hungry getSingleTon(){
        return singleTon;
    }

    /*測試*/
    public static void main(String[] args){
        for(int i=0;i<10;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Hungry.getSingleTon());
                }
            }).start();
        }
    }
}

執行結果:

com.bee.sample.ch1.practice.Hungry@64669643
com.bee.sample.ch1.practice.Hungry@64669643
com.bee.sample.ch1.practice.Hungry@64669643
... ...(忽略幾行)

【點評】是線程安全的,但是系統啓動,在類加載時,會直接new出一個對象,導致系統啓動變慢。

(2)懶漢模式

public class SynDoubleCheckLazy {
    private SynDoubleCheckLazy(){}
    private static SynDoubleCheckLazy singleTon=null;
    public static SynDoubleCheckLazy getSingleTon(){
        if(singleTon==null){
            //這個Thread.sleep僅僅爲測試多線程,製造障礙,使用時刪去
            try{
                Thread.sleep(200);
            }catch (Exception e){
                e.printStackTrace();
            }
            synchronized (SynDoubleCheckLazy.class){
                if(singleTon==null){
                    singleTon=new SynDoubleCheckLazy();
                }
            }
        }
        return singleTon;
    }

    /*以下爲測試*/
    public static void main(String[] args){
        for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(SynDoubleCheckLazy.getSingleTon());
                }
            }).start();
        }
    }
}

【點評】線程安全,且效率優良,值得推薦。兩次判斷getSingleTon 返回對象是否爲空,第一次是效率需要,如果非空,直接返回,不用進入下面的同步模塊損失效率,第二次是安全需要。

(3)私有靜態內部類模式

package com.bee.sample.ch1.practice;

public class PrivateStaticInner {
    private PrivateStaticInner(){}
    private static class PrivateStaticInnerHolder{
        private static PrivateStaticInner singleTon = new PrivateStaticInner();
    }
    public static PrivateStaticInner getSingleTon(){
        return PrivateStaticInnerHolder.singleTon;
    }

    /*測試*/
    public static void main(String[] args){
        for(int i=0;i<5;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(PrivateStaticInner.getSingleTon());
                }
            }).start();
        }
    }
}

【點評】線程安全,外貌和餓漢模式相似,兩者都是利用類加載的方式來實現初始化時只有一個線程,區別在於PrivateStaticInner 加載時,不會立刻實例化,而是調用getSingelTon方法時,纔會裝載內部類PrivateStaticInnerHolder,從而完成父類PrivateStaticInner 的實例化,值得推薦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章