Java單例模式

Java開發中常用到單例模式,如Runtime就是用到的單例模式。常用的單例模式主要有以下幾種:

  • 餓漢式單例
  • 懶漢式單例
  • final修飾的單例
  • 保證線程安全的單例
  • 枚舉型單例

餓漢式單例:也就是無論用不用實例,都會去創建實例

class Single{
    //1、私有構造方法,使外部不能創建實例
    private Single(){

    }
    //2、私有成員變量,外部不能修改

    private static Single s=new Single();
    //3、提供公共的方法,使外部得到一個實例
    public static Single GetInstance(){
        return s;
    }

懶漢式單例:需要對象時才創建,也是單例的延遲加載模式

class Single{
    //1、私有構造方法,使外部不能創建實例
    private Single(){

    }
    //2、私有成員變量,外部不能修改

    private static Single s;
    //3、提供公共的方法,使外部得到一個實例
    public static Single GetInstance(){
        if(s==null){
            s=new Single();
        }
        return s;
    }
}

final型單例:用final變量修飾

class Single{
    public static final Single s=new Single();
}

以上三種單例模式都是線程不安全的,當在多線程下就會出現多個單例的情況,也就是每個線程創建一個單例。在併發編程中,要保證線程安全,多以出現了以下兩種線程安全的模式:
volatile及synchronized修飾的單例:

class Singleton_1{
//volatile保證有序可見性、有序性,但是不保證原子性,可以禁止指令重排序
    private volatile Singleton_1 singleton;
    private Singleton_1(){}
    public Singleton_1 getInstance(){
        if(singleton==null){
        //synchronized保證原子性
            synchronized (Singleton.class){
            //防止多個線程同時執行第一個判斷語句時,會創建多個實例
                if(singleton==null){
                    singleton=new Singleton_1();
                }
            }
        }
        return singleton;
    }
}

枚舉型單例:

/**
 * 枚舉單例
 * JVM會保證Enum不能被反射,並且構造器只執行一次
 */
class EnumSingleton{
    private EnumSingleton(){}
    public static EnumSingleton getInstance(){
        return Singleton.SINGLETON.getInstance();
    }

    /**
     * 此枚舉類默認繼承Enum而不是Object
     * 枚舉類的構造器只能是私有的
     */
    private enum Singleton{
        /**
         * 枚舉類的關鍵字
         * 自動添加public static final修飾
         */
        SINGLETON;
        private EnumSingleton enumSingleton;
        //JVM保證此方法絕對只調用一次
        private Singleton(){
            enumSingleton=new EnumSingleton();
        }
        public EnumSingleton getInstance(){
            return enumSingleton;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章