java 单例 实现_java 实现单例的各种方式
概述
上一篇日志中,我們介紹了單例模式的概念和基礎的應用
本節中,我們就來介紹一下?java?語言中如何編寫單例模式類
只適合單線程環境的單例模式
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
這是單例模式的最簡單實現,private?的構造方法保證了類不會被通過?new?的方式創建,同時,判斷?instance?是否為?null?保證了單線程環境下單例模式運行的正確性
但是,正如我們反復強調的,這種方式是非線程安全的,原因在于,當多個線程并發執行,同時進行判斷?instance?為?null?的操作,而此時?instance?確實為?null,那么所有的線程都將去創建一個單例的對象,這顯然是我們不希望看到的,那么下面我們就來解決這個問題
通過同步鎖實現線程安全
正如上面提到的,之所以存在線程安全問題,主要是因為判斷?instance?是否為?null?與對象的創建是非原子性的,那么,我們只需要用鎖來保證兩個操作的原子性即可解決這個問題
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
但是加鎖對性能是會造成影響的,在并發環境下,當一個線程運行到?synchronized?處,獲取鎖進入到?instance?的判斷,其他所有的并發線程都必須在該線程執行完?instance?的創建操作后才能夠繼續執行,而事實上,一旦?instance?被創建,這樣的等待都將會是白費的
雙重校驗鎖
雙重校驗鎖對上面的例子進行了優化
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
一旦對象被創建,那么程序將不會去請求獲取鎖而是直接返回?instance
最簡單的線程安全單例模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
這段代碼看上去非常簡單,他會在類首次被加載時創建單例的對象,jvm?會保證單例對象只被創建一次,但是有時我們僅僅是在代碼中引用了這個類,或者僅僅調用了這個類中的其他方法,我們并不希望在我們還不需要通過?getInstance?方法獲取對象的時候,對象就已經被創建了,這是這種方式的主要問題
靜態內部類
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
這種方式解決了上一種方式所存在的問題,僅在?getInstance?方法被調用時,對象才會被創建
使用枚舉
public enum SingletonEnum {
BOOM_MAZE_FACTORY(new BoomMazeFactory()),
STANDARD_MAZE_FACTORY(new StandardMazeFactory()),
;
private MazeFactory mazeFactory;
public MazeFactory getMazeFactory() {
return mazeFactory;
}
SingletonEnum(MazeFactory mazeFactory) {
this.mazeFactory = mazeFactory;
}
}
由于枚舉在項目中并不會被常常用到,這樣的用法就更加難得一見了,而事實上,這才是最推薦的用法
微信公眾號
歡迎關注微信公眾號,以技術為主,涉及歷史、人文等多領域的學習與感悟,每周三到七篇推文,只有全部原創,只有干貨沒有雞湯
標簽
技術帖
技術分享
java
singleton
設計模式
模式
設計
單例
總結
以上是生活随笔為你收集整理的java 单例 实现_java 实现单例的各种方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: msci指数是什么意思?
- 下一篇: java中插入排序实例_java中对插入