單例模式是設(shè)計模式中最常用的設(shè)計模式,其實現(xiàn)也相對簡單.
單例模式指的是設(shè)計一個類,這個類的實例對象只允許存在一個.
下面介紹幾種常用的單例模式實現(xiàn)方式:
1.餓漢式--靜態(tài)變量--可用
package com.zk;
/**
* Singleton1
* @description 單例模式--餓漢式(靜態(tài)變量)
* @author zk
* @date 2018年7月24日 下午9:03:32
* @version 1.0
*/
public class Singleton1 {
//定義一個私有的靜態(tài)變量,存放這個類的實例對象,讓當(dāng)前類的get方法可以使用這個實例對象
private static Singleton1 instance = new Singleton1();
//私有的構(gòu)造器,保證只能在當(dāng)前類中新建對象
private Singleton1(){}
//提供一個公共靜態(tài)的get方法,讓其他類可以得到當(dāng)前類的實例對象
public static Singleton1 getInstance(){
return instance;
}
}
2.餓漢式--靜態(tài)代碼塊--可用
package com.zk;
/**
* Singleton2
* @description 單例模式--餓漢式(靜態(tài)代碼塊)
* @author zk
* @date 2018年7月24日 下午9:27:28
* @version 1.0
*/
public class Singleton2 {
//定義一個私有的靜態(tài)變量
private static Singleton2 instance;
//通過靜態(tài)代碼塊給私有的靜態(tài)變量賦值,指向當(dāng)前類的實例對象
static{
instance = new Singleton2();
}
//私有化構(gòu)造方法,保證只有當(dāng)前類可以創(chuàng)建實例對象
private Singleton2(){};
//公共的靜態(tài)get方法,讓其他類可以獲得實例對象
public static Singleton2 getInstance(){
return instance;
}
}
3.懶漢式--線程不安全--不可用
package com.zk;
/**
* Singleton3
* @description 單例模式--懶漢式--線程不安全,不可用
* @author zk
* @date 2018年7月24日 下午9:46:44
* @version 1.0
*/
public class Singleton3 {
private static Singleton3 instance;
private Singleton3(){};
public static Singleton3 getInstance(){
//懶加載,用到的時候才創(chuàng)建對象,但是存在線程安全問題
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}
4.懶漢式--同步方法--可用但不推薦
package com.zk;
/**
* Singleton
* @description 單例模式--懶漢式--同步方法--可用但不推薦
* @author zk
* @date 2018年7月24日 下午9:51:30
* @version 1.0
*/
public class Singleton4 {
private static Singleton4 instance;
private Singleton4(){};
//在Singleton3的基礎(chǔ)上加上了synchronized變成同步方法,解決了線程不安全問題,但有性能問題
public static synchronized Singleton4 getInstance(){
if(instance == null){
instance = new Singleton4();
}
return instance;
}
}
5.懶漢式--雙重檢查+同步代碼塊--推薦使用
package com.zk;
/**
* Singleton5
* @description 單例模式--懶漢式--雙重檢查+同步代碼塊--推薦使用
* @author zk
* @date 2018年7月24日 下午9:59:50
* @version 1.0
*/
public class Singleton5 {
private static Singleton5 instance;
private Singleton5(){}
public static Singleton5 getInstance(){
//第一次判斷
if(instance == null){
//同步代碼塊,解決線程安全問題
synchronized (instance) {
//第二次判斷
if(instance == null){
instance = new Singleton5();
}
}
}
return instance;
}
}
6.使用靜態(tài)內(nèi)部類--可用
package com.zk;
/**
* Singleton6
* @description 單例模式--靜態(tài)內(nèi)部類
* @author zk
* @date 2018年7月25日 下午9:01:32
* @version 1.0
*/
public class Singleton6 {
private Singleton6(){};
//靜態(tài)內(nèi)部類
private static class SingletonClass{
private static final Singleton6 instance = new Singleton6();
}
public static Singleton6 getInstance(){
return SingletonClass.instance;
}
}
7.使用枚舉--可用
package com.zk;
/**
* Singleton7
* @description 單例模式--枚舉
* @author zk
* @date 2018年7月25日 下午9:10:29
* @version 1.0
*/
public enum Singleton7 {
INSTANCE;
}
總結(jié):實現(xiàn)單例模式的方式有很多種,但是總結(jié)起來不外乎以下幾點:
1.私有的構(gòu)造方法,保證實例對象只能當(dāng)前類能夠創(chuàng)建
2.創(chuàng)建唯一的實例對象,并賦值給一個靜態(tài)變量
3.靜態(tài)的get方法,讓外部類通過這個方法獲取唯一的實例對象