日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【设计模式】学习笔记---单例模式

發布時間:2025/5/22 asp.net 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式】学习笔记---单例模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

學習設計模式,死記硬背是沒用的,還要從實踐中理解

日常應用中,設計模式從來都不是單個設計模式獨立使用的。在實際應用中,通常多個設計模式混合使用,你中有我,我中有你。下圖完整地描述了設計模式之間的混用關系,希望對大家有所幫助。

單例模式

單例模式(Singleton Pattern)是 Java 中最簡單的設計模式之一。這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。

這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。

注意:

1、單例類只能有一個實例。

2、單例類必須自己創建自己的唯一實例。

3、單例類必須給所有其他對象提供這一實例。

單例模式的應用場景

對于 Java 來說,單例模式可以保證在一個 JVM 中只存在單一實例。單例模式的應用場景主要有以下幾個方面。

  • 需要頻繁創建的一些類,使用單例可以降低系統的內存壓力,減少 GC。
  • 某類只要求生成一個對象的時候,如一個班中的班長、每個人的身份證號等。
  • 某些類創建實例時占用資源較多,或實例化耗時較長,且經常使用。
  • 某類需要頻繁實例化,而創建的對象又頻繁被銷毀的時候,如多線程的線程池、網絡連接池等。
  • 頻繁訪問數據庫或文件的對象。
  • 對于一些控制硬件級別的操作,或者從系統上來講應當是單一控制邏輯的操作,如果有多個實例,則系統會完全亂套。
  • 當對象需要被共享的場合。由于單例模式只允許創建一個對象,共享該對象可以節省內存,并加快對象訪問速度。如 Web 中的配置對象、數據庫的連接池等。
  • 懶漢模式

    延遲加載, 只有在真正使用的時候,才開始實例化。

    1)線程安全問題

    2)double check 加鎖優化

    3)編譯器(JIT),CPU 有可能對指令進行重排序,導致使用到尚未初始化 的實例,可以通過添加volatile 關鍵字進行修飾, 對于volatile 修飾的字段,可以防止指令重排。

    class LazySingleton{ // java5版本之前 關鍵字volatile 不能解決指令重排的問題private volatile static LazySingleton instance; // 讓構造函數為 private,這樣該類就不會被實例化private LazySingleton(){ } // 這種方式的懶加載只適用于單線程情況下public static LazySingleton getInstance() { if (instance==null){ instance=new LazySingleton(); } return instance; } // 同步,線程安全,但是效率太低// 但是單例模式只有在第一次使用的時候才會創建// 下面這種寫法就不適合了public static synchronized LazySingleton getInstance() { if (instance==null){ instance=new LazySingleton(); } return instance; } // 雙重檢驗鎖// 下面代碼看是完美,但是JVM編譯器存在指令重排的優化(有坑)public static LazySingleton getInstance() { if (instance==null){ synchronized (LazySingleton.class){ if (instance==null){ instance=new LazySingleton(); } } } return instance; } }

    餓漢模式

    類加載的 初始化階段就完成了 實例的初始化 。本質上就是借助于jvm 類加載機制,保證實例的唯一性(初始化過程只會執行一次)及線程安全(JVM以同步的形式來完成類加載的整個過程)。

    類加載過程

    1,加載二進制數據到內存中, 生成對應的Class數據結構,

    2,連接: a. 驗證, b.準備(給類的靜態成員變量賦默認值),c.解析

    3,初始化: 給類的靜態變量賦初值

    只有在真正使用對應的類時,才會觸發初始化 如( 當前類是啟動類即 main函數所在類,直接進行new 操作,訪問靜態屬性、訪問靜態方 法,用反射訪問類,初始化一個類的子類等.)

    class HungrySingleton{ private static HungrySingleton instance=new HungrySingleton(); //讓構造函數為 private,這樣該類就不會被實例化private HungrySingleton(){ } public static HungrySingleton getInstance() { return instance;} }

    靜態內部類

    1).本質上是利用類的加載機制來保證線程安全

    2).只有在實際使用的時候,才會觸發類的初始化,所以也是懶加載的一 種形式。

    class InnerClassSingleton{ private static class InnerClassHolder{private static InnerClassSingleton instance= new InnerClassSingleton(); } private InnerClassSingleton(){} public static InnerClassSingleton getInstance(){ return InnerClassHolder.instance;} }

    反射攻擊實例

    Constructor<InnerClassSingleton> declaredConstructor=InnerClassSingleton.c lass.getDeclaredConstructor(); declaredConstructor.setAccessible( true ); InnerClassSingleton innerClassSingleton=declaredConstructor.newInstance(); InnerClassSingleton instance=InnerClassSingleton.getInstance(); System.out.println(innerClassSingleton==instance);

    靜態內部類防止反射破壞

    class InnerClassSingleton { private static class InnerClassHolder{ private static InnerClassSingleton instance= new InnerClassSingleton(); } private InnerClassSingleton(){ if (InnerClassHolder.instance!=null){ throw new RuntimeException( " 單例不允許多個實例 " ); } } public static InnerClassSingleton getInstance(){ return InnerClassHolder.instance; } }

    枚舉類型

    1)天然不支持反射創建對應的實例,且有自己的反序列化機制

    2)利用類加載機制保證線程安全

    public enum EnumSingleton { INSTANCE; public void print(){ System.out.println(this.hashCode()); } }

    序列化

    1)可以利用 指定方法來替換從反序列化流中的數據 如下 1

    ANY‐ACCESS‐MODIFIER Object readResolve() throws ObjectStreamException; class InnerClassSingleton implements Serializable{ static final long serialVersionUID = 42L; private static class InnerClassHolder{ private static InnerClassSingleton instance= new InnerClassSingleton(); } private InnerClassSingleton(){ if (InnerClassHolder.instance!=null){ throw new RuntimeException( " 單例不允許多個實例 " );}} public static InnerClassSingleton getInstance(){ return InnerClassHolder.instance; } Object readResolve() throws ObjectStreamException{ return InnerClassHolder.instance; } }

    總結

    以上是生活随笔為你收集整理的【设计模式】学习笔记---单例模式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。