寫一個單例模式?

單例1:

/**
 * 單例模式-餓漢式線程安全
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton {
    /**餓漢式**/
    private static final Singleton singleton=new Singleton();

    /**私有化構造器**/
    private Singleton() {

    }
    /**提供公共靜態方法 獲取單例對象**/
    public  static Singleton getSingleton(){
        return Singleton.singleton;
    }

    public static void main(String[] args) {
     	 Singleton A= Singleton.getSingleton();
        Singleton B= Singleton.getSingleton();
        System.out.println("比較是否地址相同:"+ (A==B));
    }

}

單例2:

/**
 * 懶漢式單例,線程不安全
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton2 {
    /**沒有實例化的對象,不用final修飾**/
    private static Singleton2 singleton2;

    /**私有化構造器**/
    private Singleton2() {
    }


    /**獲取單例,沒有同步方法線程不安全**/
    public static Singleton2 getInstance() {
        //判斷對象是否實例化?
        if (singleton2 == null) {
            Singleton2.singleton2 = new Singleton2();
        }
        return singleton2;
    }

    public static void main(String[] args) {
        Singleton2 a=Singleton2.getInstance();
        Singleton2 b=Singleton2.getInstance();
        System.out.println(a==b);
    }

}

單例3:

/**
 * 懶漢式單例-線程安全的方式
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton2 {
    /**沒有實例化的對象**/
    private static Singleton2 singleton2;

    /**私有化構造器**/
    private Singleton2() {
    }


    /**獲取單例,synchronized同步方法,線程安全**/
    public static synchronized Singleton2 getInstance() {
        //判斷對象是否實例化?
        if (singleton2 == null) {
            Singleton2.singleton2 = new Singleton2();
        }
        return singleton2;
    }

    public static void main(String[] args) {
        Singleton2 a=Singleton2.getInstance();
        Singleton2 b=Singleton2.getInstance();
        System.out.println(a==b);
    }

}

單例4:

/**
 * 雙檢鎖單例模式
 * 線程安全
 *
 * @author 魏
 * @Date 2020/3/16 0016
 **/
public class Singleton3 {
    //輕量級鎖
    private volatile static Singleton3 singleton3;

    //私有構造器
    private Singleton3() {
    }

    //雙檢鎖
    public static Singleton3 getInstance() {
        //不爲空 直接返回實例,爲空進入邏輯
        if (null == singleton3) {
            //同步鎖 鎖住對象  假如同時幾個線程進入還沒有實例
            //那麼鎖住可以保證只創建一個實例對象 保證單例
            synchronized (Singleton3.class) {
                //爲空才創建對象,因爲多線程可能同時進入,那麼第一個鎖住類對象 實例化它
                //然後釋放鎖 其他線程檢查類實例化了沒? 不爲空返回對象
                if (null == singleton3) {
                    singleton3 = new Singleton3();
                }


            }
        }
        return singleton3;
    }

    public static void main(String[] args) {
        Singleton3 a = Singleton3.getInstance();
        Singleton3 b = Singleton3.getInstance();
        System.out.println(a == b);
    }

}

單例5:枚舉

/**
 * 枚舉顏色
 * @author 魏
 * @Date 2020/3/17 0017
 **/
public enum Color {
//jdk1.5後枚舉可以列舉單例  而且更豐富
//Color顏色
    YELLOW,BLANK,RED
}

/**
 * @author 魏
 * @Date 2020/3/17 0017
 **/
public class Test {
    public static void main(String[] args) {
        Color color = Color.RED;
        System.out.println(color);

    }
}


枚舉充電:

/**
 * 枚舉
 * @author 魏
 * @Date 2020/3/17 0017
 **/

public enum Singleton5 {
//有參單例,名字叫ERROR
    ERROR(0,"狀態消息:失敗"),
    //有參單例,名字叫OK
    OK(1,"狀態消息:成功");
    //成員屬性
    private  Integer status;
    private  String  msg;

    /**
    * 有參構造私有
     * @param status 狀態碼
     * @param msg  消息
     */
    private  Singleton5(Integer status,String msg){
        this.status=status;
        this.msg=msg;
    }
//get set toString
    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "Singleton5{" +
                "status=" + status +
                ", msg='" + msg + '\'' +
                '}';
    }
}

----------------------------------------------
	  Singleton5 singleton5=Singleton5.OK;
        System.out.println("枚舉:"+singleton5.toString());
     --------------------------------------
        枚舉:Singleton5{status=1, msg='狀態消息:成功'}

可以看到 我們只要有私有構造方法(有參或者無參,不寫默認提供無參),就可以直接通過 實例名稱來創建單例,前後端分離狀態碼可以使用這個來寫.

這個和我們的傳統單例模式都差不多,傳統的一般是私有化構造器,公共方法獲取一個實例化對象,你需要保證的是對象只有一個.

而枚舉是直接通過實例名字表示單例對象.
比如:

public enum Color {
    YELLOW,BLANK,RED
    //省略了無參構造
}

如果需要有參 就需要定義有參構造函數

public enum Color {
    //實例對象,每一個都是單例
    YELLOW("黃色"),BLANK("黑色"),RED("紅色");
    //構造器
    private Color(String msg){
    this.msg=msg;
    }
 private String msg;
 //省略get set等方法
}

ps:建議使用枚舉,好用又簡單啊…

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