JAVA設計模式-單例模式
單例模式
類只能有一個實體,在記憶體中會創建并且只創建一次物件,所有其他類或者其他需要呼叫的地方都是用這一個物件,可以防止頻繁創建物件,記憶體占用高,特點:只能有一個實體,并且能夠自行創建這個實體的類,
實作
餓漢模式
寫法一
介紹
在類的加載時就已經創建好物件,執行緒是安全的,但是會浪費資源,參考原始碼:JDK1.8 com.sun.glass.ui.monocle.KeyInput類

代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件
*/
private static Singleton singleton = new Singleton();
/**
* 提供公共的對外的獲取方法
* @return
*/
public static Singleton getInstance(){
return singleton;
}
}
寫法二
介紹
在類的加載時就已經創建好物件,此處是使用靜態代碼塊進行創建,執行緒是安全的,

代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件
*/
private static Singleton singleton = null;
static {
singleton = new Singleton();
}
/**
* 提供公共的對外的獲取方法
* @return
*/
public static Singleton getInstance(){
return singleton;
}
}
懶漢模式
寫法一
介紹
在第一次使用時進行創建物件,如果多個執行緒同時呼叫了getInstance()方法,可能會創建多個物件,執行緒是不安全的,

代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件,注意此處不進行new創建
*/
private static Singleton singleton;
/**
* 提供公共的對外的獲取方法
* @return
*/
public static Singleton getInstance(){
// 多個執行緒同時執行這邊時,可能會創建多個物件
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
寫法二
介紹
這種寫法也是在第一次呼叫時進行創建物件,但是在該方法上增加了synchronized同步鎖,這樣就可以保證只會有一個執行緒執行,執行緒是安全的,但是synchronized在1.6之前性能比較差,1.6之后進行了優化,性能提升,但是此處為了保證執行緒安全,使用synchronized,還是多少會影響性能,

代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件,注意此處不進行new創建
*/
private static Singleton singleton;
/**
* 提供公共的對外的獲取方法
* @return
*/
public static synchronized Singleton getInstance(){
// 第一次呼叫時進行創建物件
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
寫法三
介紹
這種寫法采用雙重鎖的方式,進行判斷并創建物件,執行緒是不安全的,

分析執行緒不安全原因:首先在記憶體中創建物件,需要進行
①分配記憶體地址
②初始化物件
③設定物件指向剛剛分配的記憶體地址
但是在編譯器、指令集并行、記憶體中都可能進行指令重排序,如果發生指令重排序,對于單執行緒來說,如果執行①③②和執行①②③的結果是一樣的,但是如果是多執行緒,在執行緒A執行完①③之后,如果執行緒B進入到第一個if陳述句,則會判斷singleton已經指向一個地址,不等于null,則直接回傳,此時回傳的物件是還未進行初始化的空物件,
代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件,注意此處不進行new創建
*/
private static Singleton singleton;
/**
* 提供公共的對外的獲取方法
* @return
*/
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
寫法四
介紹
在寫法三的基礎上,增加volatile,volatile可以禁止指令重排序并且保證共享變數不同執行緒之間的可見性,

代碼示例
public class Singleton {
/**
* 私有的構造方法,可以防止外部呼叫時new進行創建物件
*/
private Singleton(){};
/**
* 創建私有的物件,注意此處不進行new創建, 使用volatile
*/
private volatile static Singleton singleton;
/**
* 提供公共的對外的獲取方法
* @return
*/
public static Singleton getInstance(){
if(singleton == null){
synchronized (Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
原文鏈接:https://monkey.blog.xpyvip.top/archives/java-she-ji-mo-shi---dan-li-mo-shi
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/508917.html
標籤:Java
上一篇:day39-網路編程01
下一篇:java--面向物件基礎
