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

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

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

      Java設(shè)計(jì)模式-單例模式

      Java常用設(shè)計(jì)模式-單例模式

      Java Design Patterns:

      創(chuàng)建型模式:工廠方法、抽象方法、建造者、原型、單例

      結(jié)構(gòu)型模式有:適配器、橋接、組合、裝飾器、外觀、享元、代理

      行為型模式有:責(zé)任鏈、命令、解釋器、迭代器、中介、備忘錄、觀察者、狀態(tài)、策略、模板方法、訪問者

      常用設(shè)計(jì)模式:

      單例模式、工廠模式、代理模式、策略模式&模板模式、門面模式、責(zé)任鏈模式、裝飾器模式、組合模式、builder模式

      單例模式

      簡介

      確保一個類只有一個實(shí)例,并提供一個全局訪問點(diǎn)

      懶漢式:

      /**
       * 單例設(shè)計(jì)模式:確保一個類只有一個對象實(shí)例,并提供一個全局訪問點(diǎn)
       * 懶漢式:
       * 是否 Lazy 初始化:是
       * 是否多線程安全:否
       */
      public class Signleton {
          private static Signleton signleton;
          private Signleton(){}
          //可以通過synchronized關(guān)鍵字保證線程安全
          public static Signleton getSignleton(){
              if(signleton == null){
                  signleton = new Signleton();
              }
              return signleton;
          }
      }
      

      餓漢式:

      /**
       * 單例設(shè)計(jì)模式:確保一個類只有一個對象實(shí)例,并提供一個全局訪問點(diǎn)
       * 餓漢式:
       * 是否 Lazy 初始化:否
       * 是否多線程安全:是
       */
      class Signleton1{
          private static Signleton1 signleton1 = new Signleton1();
      
          private Signleton1(){}
      
          public static Signleton1 getSignleton1(){
              return signleton1;
          }
      }
      

      懶漢式:解決反射、序列化反序列化問題

      /**
       * 單例設(shè)計(jì)模式:確保一個類只有一個對象實(shí)例,并提供一個全局訪問點(diǎn)
       * 懶漢式:
       * 是否 Lazy 初始化:是
       * 是否多線程安全:否
       */
      public class Signleton implements Serializable {
          private static final long serialVersionUID = 1L;
          private static Signleton signleton;
      
          private Signleton() {
              // 防止反射
              if (signleton != null) {
                  throw new RuntimeException();
              }
          }
      
          // 可以通過synchronized關(guān)鍵字保證線程安全
          public static Signleton getSignleton() {
              if (signleton == null) {
                  signleton = new Signleton();
              }
              return signleton;
          }
      
      
          /*
          序列化:當(dāng)一個對象被序列化時,Java 將該對象的狀態(tài)寫入一個字節(jié)流。
          反序列化:當(dāng)字節(jié)流被反序列化時,Java 將創(chuàng)建一個新的對象實(shí)例,并將字節(jié)流中的數(shù)據(jù)填充到這個新實(shí)例中。
          readResolve 方法:在對象被反序列化之后,Java 會調(diào)用這個方法。如果該方法存在,返回的對象將代替默認(rèn)反序列化過程中創(chuàng)建的新對象。
           */
          private Object readResolve() {
              return signleton;
          }
      
      }
      
      
       /**
           * 反射測試
           */
          @Test
          public void test(){
              //獲取單例
              Signleton signleton = Signleton.getSignleton();
              Signleton signleton1 = Signleton.getSignleton();
              System.out.println(signleton.hashCode());
              System.out.println(signleton1.hashCode());
      
              //通過反射破壞單例
              try {
                  Class<?> aClass = Class.forName("design.patterns.Signleton");
                  Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
                  declaredConstructor.setAccessible(true);
                  Signleton signleton2 = (Signleton) declaredConstructor.newInstance();
                  System.out.println(signleton2.hashCode());
              } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException |
                       InvocationTargetException e) {
                  e.printStackTrace();
              }
          }
      
          /**
           * 序列化測試
           */
          @Test
          public void test1(){
              //獲取單例
              Signleton signleton = Signleton.getSignleton();
              Signleton signleton1 = Signleton.getSignleton();
              System.out.println(signleton.hashCode());
              System.out.println(signleton1.hashCode());
      
              //序列化反序列化獲取對象
              try {
                  ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("D:/signleton.ser"));
                  outputStream.writeObject(signleton1);
                  ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("D:/signleton.ser"));
                  Signleton signleton2 = (Signleton) inputStream.readObject();
                  System.out.println(signleton2.hashCode());
              } catch (IOException | ClassNotFoundException e) {
                  // throw new RuntimeException(e);
                  e.printStackTrace();
              }
          }
      

      懶漢式DCL(推薦):雙重檢查鎖定(Double-Checked Locking)是用于減少同步開銷,同時保證線程安全的一種優(yōu)化方法。其核心思想是:在訪問共享資源時,先進(jìn)行一次非同步的檢查,如果未初始化,再進(jìn)入同步塊進(jìn)行第二次檢查和初始化。這樣可以避免每次調(diào)用獲取實(shí)例方法時都需要進(jìn)行同步,從而提升性能。

      這里也確保序列化安全。

      /**
       * 單例設(shè)計(jì)模式:確保一個類只有一個對象實(shí)例,并提供一個全局訪問點(diǎn)
       * 懶漢式:
       * 是否 Lazy 初始化:是
       * 是否多線程安全:否
       */
      public class Signleton implements Serializable {
        	private static final long serialVersionUID = 1L;
          private static volatile Signleton signleton;
      
          private Signleton() {}
      
          public static Signleton getSignleton() {
              if (signleton == null) {
              	synchronized(Signleton.class){
              		if(signleton == null){
              		 signleton = new Signleton();
              		}
              	}
                 
              }
              return signleton;
          }
          
          /*
          序列化:當(dāng)一個對象被序列化時,Java 將該對象的狀態(tài)寫入一個字節(jié)流。
          反序列化:當(dāng)字節(jié)流被反序列化時,Java 將創(chuàng)建一個新的對象實(shí)例,并將字節(jié)流中的數(shù)據(jù)填充到這個新實(shí)例中。
          readResolve 方法:在對象被反序列化之后,Java 會調(diào)用這個方法。如果該方法存在,返回的對象將代替默認(rèn)反序列化過程中創(chuàng)建的新對象。
           */
          private Object readResolve() {
              return signleton;
          }
      }
      

      場景

      資源共享:避免頻繁的創(chuàng)建銷毀某個對象,造成存好。比如:日志文件。

      控制資源:避免過多的對象產(chǎn)生,造成其他問題。比如網(wǎng)站的計(jì)數(shù)器。

      應(yīng)用場景:

      • 日志管理器:避免頻繁創(chuàng)建和銷毀日志對象,確保日志文件只被一個實(shí)例操作,以便內(nèi)容可以正確追加。

      • 網(wǎng)站計(jì)數(shù)器:全局唯一實(shí)例用于統(tǒng)計(jì)網(wǎng)站訪問次數(shù),避免并發(fā)更新問題。

      • Windows 回收站:整個系統(tǒng)運(yùn)行過程中,回收站一直維護(hù)著唯一的一個實(shí)例。

      • 多線程的線程池:線程池需要方便控制池中的線程,單例模式確保線程池全局唯一。

        • /**
           * 單例線程池 -- 應(yīng)用場景
           */
          public class ThreadPool1 {
              private static ThreadPool1 threadPool;
              // 定義接口
              private ExecutorService executorService;
          
              private ThreadPool1() {
                  executorService = new ThreadPoolExecutor(
                          5, // 核心線程數(shù)
                          10, // 總線程數(shù)
                          60, TimeUnit.MILLISECONDS, // 存活時間和單位
                          new LinkedBlockingDeque<Runnable>(),  // 用于保存等待執(zhí)行的任務(wù)的隊(duì)列
                          new ThreadFactory() {  // 用于創(chuàng)建新線程的工廠
                              // 定義原子操作的 int 類型。它可以在多線程環(huán)境下安全地進(jìn)行自增、自減等操作而不需要同步
                              private AtomicInteger threadNumber = new AtomicInteger(1);
                              @Override
                              public Thread newThread(Runnable r) {
                                  Thread thread = new Thread(r, "CustomThreadPool-thread-" + threadNumber.getAndIncrement());
                                  // thread.setDaemon(true); // 設(shè)置為守護(hù)線程
                                  thread.setPriority(Thread.NORM_PRIORITY);
                                  return thread;
                              }
                          },
                          new ThreadPoolExecutor.CallerRunsPolicy() // 拒絕策略,當(dāng)任務(wù)隊(duì)列滿了且無法再接受任務(wù)時的處理策略
                  );
          
              }
          
              public static synchronized ThreadPool1 getThreadPool() {
                  if (threadPool == null) {
                      threadPool = new ThreadPool1();
                  }
                  return threadPool;
              }
          
              public void submitTask(Runnable runnable) {
                  executorService.submit(runnable);
              }
          
              public void shutdown() {
                  executorService.shutdown();
              }
          }
          
          
          
              /**
               * 單例線程池測試
               */
              @Test
              public void test2(){
                  Runnable runnable = () -> {
                      System.out.println(Thread.currentThread().getName() + " task is run");
                  };
          
                  // ThreadPool1.getThreadPool().submitTask(runnable);
          
                  ThreadPool1 threadPool = ThreadPool1.getThreadPool();
                  threadPool.submitTask(runnable);
                  System.out.println(threadPool.hashCode());
          
                  ThreadPool1 threadPool1 = ThreadPool1.getThreadPool();
                  threadPool1.submitTask(runnable);
                  System.out.println(threadPool1.hashCode());
              }
          
          //輸出:
          158199555
          158199555
          CustomThreadPool-thread-2 task is run
          CustomThreadPool-thread-1 task is run
          
      • SpringBoot中的大多數(shù)容器管理的Bean都是單例的,這些bean是應(yīng)用程序級別的單例,也就是說不同用戶共享同一個實(shí)例。比如@RestController、@Service、@Compoment、@Configuration注解修飾的類,默認(rèn)都是單例。

      優(yōu)點(diǎn)

      控制資源的使用

      • 實(shí)例控制:確保一個類只有一個實(shí)例,避免了多個實(shí)例導(dǎo)致的資源浪費(fèi)。例如,在數(shù)據(jù)庫連接池或線程池的設(shè)計(jì)中,單例模式確保只創(chuàng)建一個連接池或線程池實(shí)例,從而控制資源的使用。
      • 節(jié)省資源:減少了系統(tǒng)的開銷,避免了重復(fù)創(chuàng)建和銷毀對象的高昂成本。

      全局訪問點(diǎn)

      • 統(tǒng)一管理:通過提供一個全局訪問點(diǎn),可以方便地管理和訪問實(shí)例。比如,在日志記錄系統(tǒng)中,通過單例模式可以確保所有日志記錄都通過同一個實(shí)例進(jìn)行處理,從而統(tǒng)一日志的輸出格式和內(nèi)容。
      • 一致性:所有對該實(shí)例的操作都通過統(tǒng)一的接口進(jìn)行,確保了數(shù)據(jù)的一致性和完整性。

      易于擴(kuò)展

      • 延遲實(shí)例化:懶漢式單例模式在首次使用時才創(chuàng)建實(shí)例,避免了不必要的資源浪費(fèi)。這種延遲加載的特性也便于在系統(tǒng)啟動時減少初始化時間。

      缺點(diǎn)

      潛在的資源爭用

      • 資源競爭:如果單例類內(nèi)部使用了共享資源,而這些資源在高并發(fā)場景下沒有妥善處理,可能導(dǎo)致資源競爭問題。例如,某個單例實(shí)例持有數(shù)據(jù)庫連接對象,在高并發(fā)請求下可能導(dǎo)致連接池枯竭。

      單點(diǎn)故障

      • 故障影響范圍大:如果單例實(shí)例出現(xiàn)問題,整個系統(tǒng)的相關(guān)功能可能會受到影響。例如,日志記錄系統(tǒng)的單例實(shí)例出現(xiàn)異常,可能導(dǎo)致整個系統(tǒng)無法正常記錄日志。

      難以測試

      • 測試復(fù)雜性:由于單例模式在整個應(yīng)用程序中只有一個實(shí)例,單元測試時可能會導(dǎo)致測試的隔離性和獨(dú)立性變差。例如,一個單例類的狀態(tài)在多個測試方法之間共享,可能導(dǎo)致測試結(jié)果互相影響。

      隱藏依賴關(guān)系

      • 依賴性不明確:單例模式通過全局訪問點(diǎn)訪問實(shí)例,可能會導(dǎo)致類與類之間的依賴關(guān)系變得不清晰。例如,一個類可能隱式依賴于某個單例類的狀態(tài),增加了系統(tǒng)的復(fù)雜性和維護(hù)成本。
      posted @ 2024-07-24 22:52  Liberty碼農(nóng)志  閱讀(74)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 免费A级毛片樱桃视频| 99riav精品免费视频观看| 亚洲 欧美 影音先锋| 亚洲免费最大黄页网站| 人妻少妇偷人一区二区| 少妇高潮惨叫喷水在线观看| 久久亚洲日本激情战少妇| 国产一区在线播放av| 在线 欧美 中文 亚洲 精品| 极品尤物被啪到呻吟喷水| 国产无人区码一区二区| 中国女人和老外的毛片| 久久亚洲女同第一区综合| 不卡国产一区二区三区| 亚洲欧美国产日韩天堂区| 色综合久久中文综合久久激情| 国产SUV精品一区二区88L| 亚洲成在人线在线播放无码| 任我爽精品视频在线播放| 国产旡码高清一区二区三区 | 97碰碰碰免费公开在线视频| 国产av一区二区不卡| 天堂俺去俺来也www色官网| 国产中文一区卡二区不卡| 日本熟妇XXXX潮喷视频| 西丰县| 国产亚洲精品综合一区二区| 国产欧美丝袜在线二区| 亚洲熟女精品一区二区| 少妇激情一区二区三区视频| 色AV专区无码影音先锋| 少妇人妻偷人精品免费| 丰满人妻跪趴高撅肥臀| 无码国产偷倩在线播放老年人| 久久午夜夜伦鲁鲁片免费无码| 国产麻豆一区二区精彩视频| 日韩国产成人精品视频| 国产午夜亚洲精品国产成人| 亚洲成在人线在线播放无码| 欧美色欧美亚洲高清在线观看| 国产精品亚洲А∨天堂免下载|