單例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:建議使用枚舉,好用又簡單啊…