中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java單例模式的用法

發布時間:2021-08-26 20:18:11 來源:億速云 閱讀:125 作者:chen 欄目:編程語言

這篇文章主要講解了“Java單例模式的用法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Java單例模式的用法”吧!

單例模式的應用場景:

  單例模式(Singleton Pattern)是指確保一個類在任何情況下都絕對只有一個實例。并提供一個全局反訪問點。單例模式是創建型模式。單例模式在生活中應用也很廣泛,比如公司CEO只有一個,部門經理只有一個等。JAVA中ServletCOntext,ServetContextCOnfig等,還有spring中ApplicationContext應用上下文對象,SessionFactory,數據庫連接池對象等。使用單例模式可以將其常駐于內存,可以節約更多資源。

寫法:

  1:懶漢模式(線程不安全)

/** * 線程不安全的懶漢式單利模式 *  * Created by gan on 2019/11/17 17:33. */public class LazySingleton {  private static LazySingleton instance;  //構造方法私有化  private LazySingleton() {  }  public static LazySingleton getInstance() {    if (instance != null) {      instance = new LazySingleton();    }    return instance;  }}

  上面的代碼,提供一個靜態對象instance,構造函數私有化防止外部創建對象,提供一個靜態的getInstance方法來給訪問者一個單例對象。這種寫法的缺點就是沒有考慮到線程安全問題,當多個訪問者同時訪問的時候很有可能創建多個對象。之所以叫懶漢式,是因為這種寫法是使用的時候才創建,起到了懶加載Lazy loading的作用,實際開發中不建議采用這種寫法。

  2:線程安全的懶漢式(加鎖)

/** * 線程安全的懶漢式單利模式 *  * Created by gan on 2019/11/17 17:33. */public class LazySingleton {  private static LazySingleton instance;  //構造方法私有化  private LazySingleton() {  }  public synchronized static LazySingleton getInstance() {    if (instance != null) {      instance = new LazySingleton();    }    return instance;  }}

  這種寫法就是在第一種的基礎上添加了synchronized關鍵字保證了線程安全。這種寫法在并發高的時候雖然保證了線程安全,但是效率很低,高并發的時候所有訪問的線程都要排隊等待,所以實際開發中也不建議采用。

  3:惡漢式(線程安全)

/** * 餓漢式(線程安全) * Created by gan on 2019/10/28 22:52. */public class HungrySigleton {  public static final HungrySigleton instance = new HungrySigleton();  private HungrySigleton(){}  public static HungrySigleton getInstance(){    return instance;  }}

  直接在運行(加載)這個類的時候創建了對象,之后直接訪問。顯然這種方式沒有起到Lazy loading的效果。但是是線程安全的,實際開發中還是比較常用。

  4:靜態內部類(線程安全)

/** * 靜態內部類方式 * Created by gan on 2019/11/17 17:46. */public class StaticInnerClassSingleton {  //構造方法私有化  private StaticInnerClassSingleton() {}  //內部類  private static class HolderInnerClass {    //需要提供單利對象的外部類作為靜態屬性加載的時候就初始化    private static StaticInnerClassSingleton instance = new StaticInnerClassSingleton();  }  //對外暴漏訪問點  public static StaticInnerClassSingleton getInstance() {    return HolderInnerClass.instance;  }}

  這種內部類跟餓漢式單例有很多相似的地方,相比餓漢式單例模式的區別也是好處在于:靜態內部類不在單例類加載時就加載,而是在調用getInstance()方法的時候才進行加載,達到了類似于懶漢式的效果,而且這種方法又是線程安全的。實際開發中也建議采用。

  5:枚舉方法單例(線程安全)

/** * 枚舉單利模式 * Created by gan on 2019/11/17 17:57. */public enum EnumSingleton {  INSTANCE;  public void otherMetthod() {    System.out.println("需要單利對象調用的方法。。。");  }}

  Effective Java作者Josh Bloch提倡的方式,好處有如下:

  1:自由串行化。

  2:保證了一個實例

  3:線程安全

  這種方式防止了單例模式被破壞,而且簡潔寫法簡單,而且絕對的線程安全,但是有個缺點就是不能繼承。

  6:雙重檢查法(通常線程安全,低概率不安全)

/** * Double check * Created by gan on 2019/11/17 18:03. */public class DoubleCheckSingleton {  private static DoubleCheckSingleton instance;  private DoubleCheckSingleton() {}  public static DoubleCheckSingleton getInstance() {    if (instance == null) {      synchronized (DoubleCheckSingleton.class) {        if (instance == null) {          instance = new DoubleCheckSingleton();        }      }    }    return instance;  }}

  上面的這種寫法在并發極高的時候也可能會出現問題(當然這種概率非常小,但是畢竟還是有的嘛),解決的方案就是給instance的聲明加上volatile關鍵字即可。于是就出現了下面第7總寫法。

  7:Double check(volatile)

/** * Double check volatile * Created by gan on 2019/11/17 18:03. */public class DoubleCheckSingleton {  private volatile static DoubleCheckSingleton instance;  private DoubleCheckSingleton() {}  public static DoubleCheckSingleton getInstance() {    if (instance == null) {      synchronized (DoubleCheckSingleton.class) {        if (instance == null) {          instance = new DoubleCheckSingleton();        }      }    }    return instance;  }}

volatile關鍵字的其中一個作用就是禁止指令重排序,把instance聲明volatile后,對它的操作就會有一個內存屏障(什么是內存屏障?),這樣在賦值完成之前,就不會調用讀操作。這里具體的原因網上也是眾說紛紜,這里不進行具體闡述。

  8:ThreadLocal實現單例模式(線程安全)

/** * ThreadLocal實現單利模式 * Created by gan on 2019/11/17 18:17. */public class ThreadLocalSingleton {  private static final ThreadLocal<ThreadLocalSingleton> threadLocal = new ThreadLocal() {    @Override    protected ThreadLocalSingleton initialValue() {      return new ThreadLocalSingleton();    }  };  private ThreadLocalSingleton(){}  public static ThreadLocalSingleton getInstance(){    return threadLocal.get();  }}

  ThreadLocal會為每個線程提供一個獨立的變量副本,從而隔離了多個線程堆數據的訪問沖突。對于多線程資源共享問題,同步機制采用了“以時間換空間”的方式,而ThreadLocal則采用了“以空間換時間”的方式(主要就是避免了加鎖排隊)。 前者提供一份變量,讓不同的線程排隊訪問,而后者為每一個線程提供了一份變量,因此可以同時訪問而互不影響。但是實際是創建了多個單例對象的。

單例模式的破壞:

  1:序列化破壞

    一個對象創建好以后,有時候需要將對象序列化然后寫入磁盤。下次在從磁盤中讀取并反序列化,將其轉化為內存對象。反序列化后的對象會重新分配內存,即創建型的對象。這樣就違背了單例模式的初衷。解決這種方式的方法就是在單例類中新增一個 private Object readResolve();方法即可,具體原因可以看看序列化和反序列化的源碼。

  2:反射

    通過反射“暴力破解”也能破壞單例模式,具體暫時不闡述。

  3:克隆

    克隆也會破壞單例模式,具體暫時不闡述。

感謝各位的閱讀,以上就是“Java單例模式的用法”的內容了,經過本文的學習后,相信大家對Java單例模式的用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

方山县| 安乡县| 肇州县| 琼海市| 平远县| 奉化市| 甘孜县| 青阳县| 尼木县| 宁城县| 常熟市| 湘潭市| 台中市| 穆棱市| 东至县| 日照市| 定陶县| 宁陵县| 札达县| 新龙县| 云梦县| 井冈山市| 天峨县| 琼海市| 晋宁县| 瑞丽市| 苍梧县| 桐乡市| 彩票| 大竹县| 寿光市| 金山区| 皮山县| 内黄县| 贵德县| 聊城市| 长白| 咸丰县| 沙湾县| 兰考县| 巴中市|