<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      模式-單例模式-java

      前言

      最近看Effective Java看到了一點關于單例模式的內容,結合自己所知,在此做個總結歸納。

      單例模式

      單例模式(Singleton Pattern)是一種常用的軟件設計模式,用于限制一個類的實例化次數,確保在整個程序運行期間,該類只有一個實例存在,并提供一個全局訪問點來訪問這個實例。

      單例模式的幾種實現方式

      普遍來說,單例模式的實現主要有兩種方式:

      • ? 餓漢式:類加載時該單實例對象被創建。
      • 懶漢式:首次使用該對象時,該單實例對象才會被創建。

      補充:

      • 枚舉

      餓漢式

      • 思路:在類加載時就創建好一個靜態實例,因此類加載器保證了單例的唯一性。
      餓漢式-靜態變量寫法
      • 優點:簡單易懂,不需要加鎖。
      • 缺點:無論是否需要,都會在類加載時創建實例,可能造成資源浪費。
      public class Singleton {
          private static final Singleton INSTANCE = new Singleton();
      
          private Singleton() {}
      
          public static Singleton getInstance() {
              return INSTANCE;
          }
      }
      
      餓漢式-靜態代碼塊寫法
      • 實現邏輯與靜態變量寫法寫法基本一致,優缺點同上。
      public class Singleton {
          private static final Singleton INSTANCE ;
      
      	static{
      	INSTANCE  = new Singleton()
      	}
          private Singleton() {}
      
          public static Singleton getInstance() {
              return INSTANCE;
          }
      }
      

      懶漢式

      • 總體思想:在第一次使用時才創建實例。
      懶漢式-經典寫法
      • 思想:第一次使用時才創建實例。
      • 優點:可以延遲加載。
      • 缺點:在多線程環境下可能會產生多個實例,需要加鎖來保證線程安全。
      public class Singleton {
          private static Singleton instance;
      
          private Singleton() {}
      
          public static Singleton getInstance() {
              if (instance == null) {//在多線程情況下,理論上有可能出現多個線程同時進入了該判斷體。
                  instance = new Singleton();
              }
              return instance;
          }
      }
      
      懶漢式-同步方法(不推薦)
      • 思想:在每次調用getInstance方法時都進行同步,從而確保即使在多線程環境下,也不會創建出多個實例。
      • 優點:延遲加載、線程安全。
      • 缺點:我們知道,絕大大部分情況下資源沖突并不會頻繁發生,而每次調用getInstance方法時都需要進行同步操作,這會導致性能下降。尤其是在高并發情況下,同步操作可能會成為瓶頸。
      public class Singleton {
          private static Singleton instance;
      
          private Singleton() {}
      
          public static synchronized  Singleton getInstance() {
              if (instance == null) {//在多線程情況下,理論上有可能出現多個線程同時進入了該判斷體。
                  instance = new Singleton();
              }
              return instance;
          }
      }
      
      懶漢式-雙重檢查鎖(推薦)
      • 思想:使用雙重檢查鎖定(Double-Checked Locking),只在必要時進行同步。
      • 優點:延遲加載,并且線程安全。
      • 缺點:實現稍微復雜一些。
      public class Singleton {
          private volatile static Singleton instance;//注意volatile 
      
          private Singleton() {}
      
          public static Singleton getInstance() {
              if (instance == null) {//檢查是否未初始化
                  synchronized (Singleton.class) {//注意,在一個線程拿到鎖后,可能有多個線程阻塞在該部分,在當前線程完成初始化操作后,他們也是有機會拿到鎖的,因而需要在鎖內部再加一個判斷
                      if (instance == null) {//為了保證其他線程對instance的可見性,instance 應該聲明為volatile 
                          instance = new Singleton();
                      }
                  }
              }
              return instance;
          }
      }
      

      注意:

      • 在雙重檢查鎖定中,instance變量需要被聲明為volatile,以確保多線程環境下對instance的可見性和有序性
      懶漢式-靜態內部類(推薦)
      • 思想:控制類加載的時機,利用類加載機制保證初始化實例時只有一個線程。
      • 優點:既實現了懶加載,又能保證線程安全,而且代碼簡潔。
      public class Singleton {
          private static class LazyHolder {
              private static final Singleton INSTANCE = new Singleton();
          }
      
          private Singleton() {}
      
          public static Singleton getInstance() {
              return LazyHolder.INSTANCE;
          }
      }
      

      存在的問題

      簡單來說,私有構造方法并不是絕對安全的,仍可通過一定方式拿到它,請看如下代碼:

      public static void main(String[] args) throws Exception {
      
              Singleton s = Singleton.getInstance();//這個Singleton可以是以上某一個
              Constructor<Singleton > constructor = Singleton .class.getDeclaredConstructor();
              constructor.setAccessible(true);//打開可訪問性
              Singleton sf = constructor.newInstance();//獲取其無參構造方法
              System.out.println(s == sf);//比較引用
          }
      

      在此情況下,我們通過反射拿到了該類的一個實例,與原實例比較引用,會發現,其指向并不相同。
      當然,反射問題屬于比較極端的問題。但是,其在序列化和反序列化下也并不安全,假設我們的實例類實現了 Serializable接口(以上代碼未實現)。

       Singleton s = Singleton.getInstance();//這個Singleton可以是以上某一個
       byte[] serialize = SerializationUtils.serialize(s);
       Object deserialize = SerializationUtils.deserialize(serialize);
       System.out.println(s == deserialize); //true or false --> false
      

      與原實例比較引用,會發現,其指向并不相同。關于這一部分,實際上有個機制:

      當一個實現了Serializable接口的單例對象被序列化后,再通過反序列化操作恢復時,默認情況下會生成一個新的對象實例。這意味著即使原始對象是單例的,反序列化后的對象也將是一個新的實例。

      為了保證序列化安全,需要在單例類中定義readResolve方法。這個方法將在反序列化過程中被調用,用來返回一個替代對象。通過readResolve方法返回單例的現有實例,可以確保序列化和反序列化過程中始終只有一個實例。如:

      public class Singletonimplements Serializable {
      
          private static class LazyHolder {
              private static final SingletonINSTANCE = new MyTest();
          }
      
          private Singleton() {
          }
      
          public static final SingletongetInstance() {
              return LazyHolder.INSTANCE;
          }
      
          private Object readResolve() {//see 
              return LazyHolder.INSTANCE;
          }
       }
      

      枚舉(天然適合)

      事實上,枚舉實現單例模式的方式是基于語言級別的支持,它不僅簡潔,而且天然具備線程安全性和序列化安全性。
      比如:

      • 反射安全方面:在Constructor源碼中,當調用newInstance創建對象時,會檢查該類是否為ENUM,如果是則拋出異常,也就是說即使拿到了該枚舉類的構造方法,也無法通過反射來建立它的實例。
      • 序列化安全方面:當枚舉對象被序列化時,只會將枚舉常量的名字(name)輸出到結果中,而不是整個對象的狀態。在反序列化時,Java 會通過調用 java.lang.Enum.valueOf(Class, String) 方法來根據名字查找枚舉常量,而不是創建一個新的枚舉對象。。
      • 線程安全:由反編譯可知,枚舉常量的初始化是在靜態代碼塊中完成的,在類加載時完成初始化,而類加載是由JVM保證線程安全的。
      public enum Elvis {
          INSTANCE;
      
          public void leaveTheBuilding() {
              System.out.println("Elvis has left the building.");
          }
      }
      

      總結

      • 餓漢式:在類加載時創建實例,簡單易懂,無需加鎖。
      • 懶漢式:延遲創建實例,需考慮線程安全問題。
        • 經典寫法:非線程安全。
        • 同步方法:線程安全但性能較差。
        • 雙重檢查鎖(DCL):線程安全且性能較好。
        • 靜態內部類:線程安全且簡潔。
      • 枚舉:簡潔且天然具備線程安全性和序列化安全性,防止反射破壞。
      posted @ 2024-09-11 14:59  li-羨魚  閱讀(37)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 蜜臀av人妻国产精品建身房| 精品精品亚洲高清a毛片| 大尺度国产一区二区视频| 成人嫩草研究院久久久精品| 18禁黄无遮挡网站免费| 少妇和邻居做不戴套视频| 人妻中出无码一区二区三区| 亚洲精品码中文在线观看| 美欧日韩一区二区三区视频| 大香伊蕉在人线国产免费| 国产一二三五区不在卡| 亚洲中文字幕无码一久久区| 免费无码成人AV片在线| 少妇人妻互换不带套| 性色av无码不卡中文字幕| 中文字幕人妻av12| 久久精品国产久精国产| 国产va免费精品观看| 免费国产精品黄色一区二区| 国产成人精品无码免费看| 国99久9在线 | 免费| 久久久精品2019中文字幕之3| 亚洲成av人片色午夜乱码| 免费看视频的网站| 成人午夜福利精品一区二区| 尤物yw193无码点击进入| 亚洲黄色片一区二区三区| 中文字幕理伦午夜福利片| 亚洲国产欧美不卡在线观看| 我要看亚洲黄色太黄一级黄| 福利一区二区不卡国产| 狠狠色婷婷久久综合频道日韩 | 亚洲国产午夜精品理论片| 护士张开腿被奷日出白浆| 天堂…中文在线最新版在线| 99福利一区二区视频| 色欲av蜜桃一区二区三| 国产丰满乱子伦午夜福利| 亚洲精品中文av在线| 欧美最猛黑人xxxx| 亚洲一级片一区二区三区|