Java 設計模式之單例模式

      網友投稿 1024 2025-03-31

      1 簡介


      單例模式保證一個類只有一個實例,并向外提供一個全局的訪問入口,單例類需自己實例化唯一的實例。Java 中 java.lang.Runtime 就是典型的單例模式實現例子,現實生活中的例子也比較多,比如:一個學校有一個校長、一個公司有一個董事長等。

      優點:因為單例模式只生成一個實例,所以能夠節約系統資源、減少性能開銷,同時也能避免對共享資源的多重占用。

      缺點:同樣因為只有一個實例,導致單例類的職責過重,與單一職責原則沖突,它沒有接口,不能繼承,不利于擴展。

      2 實現方式

      常見的單例模式實現方式大致有五種,分別為:餓漢式、懶漢式、雙重檢測鎖、靜態內部類、枚舉,通常我們需要保證單例模式的線程安全,下面來看一下如何通過這五種方式實現線程安全的單例模式。

      2.1 餓漢式

      餓漢式從字面上我們就能了解個大概:餓了就要馬上吃飯,這種模式在類加載時就初始化實例,缺點是容易產生垃圾對象,因為可能我們還沒有用到實例的時候,實例就已經被創建了;優點是線程安全,不用加鎖,效率高。示例如下:

      public class Singleton { private static Singleton instance = new Singleton(); //將構造器設置為 private,禁止通過 new 實例化 private Singleton() {} public static Singleton getInstance() { return instance; } }

      2.2 懶漢式

      懶漢式就是懶加載,在首次調用時進行初始化,避免了內存被浪費問題,但這種方式在多線程情況下需要通過加鎖(如:synchronized )來保證線程安全,加鎖會影響效率,因此這種方式效率可能會比較低。示例如下:

      public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { synchronized(Singleton.class) { if (instance == null) { instance = new Singleton(); } } return instance; } }

      2.3 雙重檢測鎖

      這種方式采用雙鎖機制,在多線程情況下既能保證線程安全,同時又能保持較高的性能,當然這種方式實現會相對復雜了一點。示例如下:

      Java 設計模式之單例模式

      public class Singleton { private volatile static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }

      從示例中我們可以看到,這種方式進行了兩次判斷,第一次是為了避免不要的實例創建,第二次是為了進行同步,避免多線程問題。instance = new Singleton() 創建時在 JVM 中可能會進行指令重排序,在多線程情況下會存在線程安全問題,使用 volatile 修飾 instance 解決該問題。

      2.4 靜態內部類

      這種方式和餓漢式一樣,通過 ClassLoader 的機制保證了線程安全,不同之處餓漢式一旦 Singleton 類被裝載了,那么 instance 就會被實例化,而這種方式只有內部類(SingletonInner)被主動使用時才會實例化單例對象;該方式可以達到雙重檢測鎖方式的效率,實現相對簡單一點,當然這種方式只適用于靜態域的情況,雙重檢測鎖方式可在實例域需要延遲初始化時使用。

      示例如下:

      public class Singleton { private static class SingletonInner { private static final Singleton instance = new Singleton(); } private Singleton() {} public static final Singleton getInstance() { return SingletonInner.instance; } }

      2.5 枚舉

      默認枚舉實例的創建是線程安全的,它自動支持序列化機制,可避免反射,防止多次實例化,因此在任何情況下都是單例的,它的實現也比較簡單,但由于 JDK1.5 之后才加入 enum,這種方式在實際工作中用的還是比較少。示例如下:

      public enum Singleton { INSTANCE; public void getInstance() {} }

      3 總結

      懶漢式效率最低;

      單例對象占用資源少,不需要延時加載,枚舉方式優于餓漢式;

      單例對象占用資源多,需要延時加載,靜態內部類優于懶漢式。

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:定制家居門店倉庫管理,提升效率與用戶體驗
      下一篇:如何對齊Excel中剩余的美元符號?
      相關文章
      亚洲精品第一国产综合亚AV| 亚洲国产精品成人久久久| 亚洲成AV人综合在线观看| 亚洲精品无码Av人在线观看国产| 国产亚洲女在线线精品| 亚洲av综合日韩| 国产精品亚洲av色欲三区| 亚洲高清一区二区三区电影| 国内精品久久久久影院亚洲 | av无码东京热亚洲男人的天堂| 亚洲精品无码久久久久YW| 亚洲色中文字幕在线播放| 亚洲狠狠成人综合网| 亚洲久悠悠色悠在线播放| 亚洲AV无码乱码在线观看代蜜桃| 亚洲精品视频久久| 亚洲国产成人综合| 亚洲AV无码专区在线亚| 亚洲乱码在线卡一卡二卡新区| 91在线亚洲综合在线| 亚洲精品无码少妇30P| 色五月五月丁香亚洲综合网| 亚洲A∨午夜成人片精品网站| 亚洲AV中文无码乱人伦在线视色| 亚洲国产综合精品中文字幕 | 亚洲视频在线观看网址| 亚洲福利视频网址| www.亚洲日本| 亚洲精品久久无码av片俺去也| 国产精品亚洲专区无码牛牛| 亚洲AV电影天堂男人的天堂| 亚洲国产a级视频| 337p日本欧洲亚洲大胆裸体艺术| 国产v亚洲v天堂无码网站| 日木av无码专区亚洲av毛片| 亚洲午夜电影在线观看| 国产亚洲精品bv在线观看| 精品亚洲成a人在线观看| 国产偷窥女洗浴在线观看亚洲 | 亚洲熟女精品中文字幕| 成人伊人亚洲人综合网站222|