Java 單例模式實現方式

Java 單例模式實現方式

??單例模式是確保一個類只有一個實例,并提供一個全局訪問點的設計模式。以下是 Java 中實現單例模式的幾種常見方式:

1. 餓漢式(Eager Initialization)

public class EagerSingleton {// 類加載時就初始化private static final EagerSingleton INSTANCE = new EagerSingleton();// 私有構造函數private EagerSingleton() {}public static EagerSingleton getInstance() {return INSTANCE;}
}

特點

  • 線程安全(由JVM類加載機制保證)
  • 簡單直接
  • 可能造成資源浪費(即使不用也會創建實例)

2. 懶漢式(Lazy Initialization,非線程安全)

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

問題

  • 非線程安全,多線程環境下可能創建多個實例

3. 懶漢式(同步方法,線程安全但效率低)

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

特點

  • 線程安全
  • 每次獲取實例都需要同步,性能較差

4. 雙重檢查鎖定(Double-Checked Locking)

public class DCLSingleton {// 使用volatile禁止指令重排序private static volatile DCLSingleton instance;private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance == null) { // 第一次檢查synchronized (DCLSingleton.class) {if (instance == null) { // 第二次檢查instance = new DCLSingleton();}}}return instance;}
}

特點

  • 線程安全
  • 只有第一次創建時需要同步
  • Java 5+ 需要配合 volatile 使用

5. 靜態內部類(Holder模式,推薦)

public class HolderSingleton {private HolderSingleton() {}private static class SingletonHolder {private static final HolderSingleton INSTANCE = new HolderSingleton();}public static HolderSingleton getInstance() {return SingletonHolder.INSTANCE;}
}

優點

  • 線程安全(由JVM類加載機制保證)
  • 懶加載(只有調用getInstance()時才加載內部類)
  • 無同步開銷
  • 目前最推薦的方式

6. 枚舉實現(Effective Java推薦)

public enum EnumSingleton {INSTANCE;public void doSomething() {// 業務方法}
}

優點

  • 線程安全
  • 防止反射攻擊
  • 防止反序列化重新創建對象
  • 代碼簡潔
  • Joshua Bloch在《Effective Java》中推薦的方式

如何選擇

  1. 簡單場景:餓漢式或枚舉方式
  2. 需要懶加載:靜態內部類方式
  3. 非常注重性能:雙重檢查鎖定(但要注意正確實現)
  4. 最佳實踐推薦:枚舉方式或靜態內部類方式

注意事項

  1. 防止反射攻擊:可以在構造函數中添加檢查
  2. 防止反序列化:實現readResolve()方法
  3. 在分布式/集群環境中,這些單例實現僅適用于單個JVM

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/85160.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/85160.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/85160.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字化零售如何全面優化顧客體驗

一、引言 數字化零售是互聯網、大數據、人工智能等技術在零售業中的應用,是現代零售業發展的必然趨勢。隨著線上購物、移動支付和全渠道銷售的普及,零售行業發生了顛覆性的變化。數字化零售不僅提高了企業運營效率,更為顧客提供了便捷、個性化…

rabbitmq 交換機、隊列和消息概念

RabbitMQ 是一個功能強大的消息中間件,它采用發布-訂閱模式進行消息傳遞。下面為你詳細介紹 RabbitMQ 中交換機、隊列和消息的核心概念。 交換機(Exchange) 交換機在 RabbitMQ 中扮演著接收生產者發送消息的角色,它會根據特定的…

記錄一次jenkins slave因為本地安裝多個java版本導致的問題

今天,使用jenkins打包,發現slave掉線,上對應機器一看,好家伙,slave運行不起來了。命令行,java -vesion. 沒反應,不會是哪個天殺的把java 給卸載了吧! 趕緊 where java看下。 還好 ja…

Java中Redis常用的API及其對應的原始API

相信大家寫redis的時候經常忘記一些指令吧[狗頭][狗頭],這里整理了一下 一、 String(字符串類型) 1.代碼塊 // 設置字符串值 stringRedisTemplate.opsForValue().set("key", "value"); // Redis: SET key value// 設置…

C#使用ExcelDataReader高效讀取excel文件寫入數據庫

分享一個庫ExcelDataReader ,它專注讀取、支持 .xls/.xlsx、內存優化。 首先安裝NuGet 包 dotnet add package ExcelDataReader dotnet add package System.Text.Encoding.CodePages 編碼 內存優化??:每次僅讀取一行,適合處理百萬級數據…

雪豹速清APP:高效清理,暢享流暢手機體驗

在智能手機的日常使用中,隨著時間的推移,手機中會積累大量的垃圾文件,如臨時文件、緩存數據、無用的安裝包等。這些垃圾文件不僅會占用寶貴的存儲空間,還會導致手機運行緩慢,甚至出現卡頓現象。為了解決這一問題&#…

關于使用v-bind綁定多個屬性值的問題

背景。自定義表單開發。屬性值過多,都寫死很臃腫而且不方便維護。通過v-bind綁定非常方便。但是問題又來了。改以怎樣的方式處理呢。返回值的格式需要注意 下面是兩張動態處理v-bind屬性的方法。第一張是寫在了方法里面,第二張使用了虛擬屬性。使用虛擬…

基于CNN的FashionMNIST數據集識別6——DenseNet模型

源碼 import torch from torch import nn from torchsummary import summary""" DenseNet的核心組件:稠密層(DenseLayer) 實現特征復用機制,每個層的輸出會與所有前序層的輸出在通道維度拼接 """class DenseLayer(nn.Mod…

MySQL 中 INSERT ... ON DUPLICATE KEY UPDATE 為什么會導致主鍵自增失效?

最近開發的過程中,使用ai生成代碼,寫了一條這樣的SQL:INSERT … ON DUPLICATE KEY UPDATE,然后發現一個奇怪的現象: 為什么使用這個語法后,自增主鍵(AUTO_INCREMENT)的值會跳躍甚至…

jenkins流水線打包vue無權限

jenkins在使用npm命令進行拉取依賴時,創建目錄會報錯無權限,如下如所示 這是因為npm 出于安全考慮不支持以 root 用戶運行,即使你用 root 用戶身份運行了,npm 會自動轉成一個叫 nobody 的用戶來運行,而這個用戶權限非常低 若需要…

快速實現golang的grpc服務

文章目錄 1、安裝服務2、檢查安裝版本情況3、編寫proto文件4、生成代碼5、實現業務邏輯6、創建provider7、測試調用 1、安裝服務 1、protoc安裝 需去官網下載 protobuf 2、命令行安裝protoc-gen-go和protoc-gen-go-grpc $ go install google.golang.org/protobuf/cmd/protoc-…

C++ 學習 多線程 2025年6月17日18:41:30

多線程(標準線程庫 <thread>) 創建線程 #include <iostream> #include <thread>void hello() {std::cout << "Hello from thread!\n"; }int main() {// 創建線程并執行 hello() std::thread t(hello); //線程對象&#xff0c;傳入可調用對…

常見的測試工具及分類

Web測試工具是保障Web應用質量的核心支撐&#xff0c;根據測試類型&#xff08;功能、性能、安全、自動化等&#xff09;和場景需求&#xff0c;可分為多個類別。以下從??八大核心測試類型??出發&#xff0c;梳理常見工具及其特點、適用場景&#xff1a; ??一、功能測試工…

七牛存儲sdk在springboot完美集成和應用 七牛依賴 自動化配置

文章目錄 概要依賴配置屬性配置類配置文件業務層控制層運行結果亮點 概要 七牛存儲很便宜的&#xff0c;在使用項目的用好官方封裝好的sdk&#xff0c;結合springboot去使用很方便&#xff0c;我本地用的是springoot3spring-boot-autoconfigure 依賴 <dependency><…

Java相關-鏈表-設計鏈表-力扣707

你可以選擇使用單鏈表或者雙鏈表&#xff0c;設計并實現自己的鏈表。 單鏈表中的節點應該具備兩個屬性&#xff1a;val 和 next 。val 是當前節點的值&#xff0c;next 是指向下一個節點的指針/引用。 如果是雙向鏈表&#xff0c;則還需要屬性 prev 以指示鏈表中的上一個節點…

C# 關于LINQ語法和類型的使用

常用語法&#xff0c;具體問題具體分析 1. Select2. SelectMany3. Where4. Take5. TakeWhile6. SkipWhile7. Join8. GroupJoin9. OrderBy10. OrderByDescending11. ThenBy12. Concat13. Zip14. Distinct15. Except16. Union17. Intersect18. Concat19. Reverse20. SequenceEqua…

華為OD-2024年E卷-小明周末爬山[200分] -- python

問題描述&#xff1a; 題目描述 周末小明準備去爬山鍛煉&#xff0c;0代表平地&#xff0c;山的高度使用1到9來表示&#xff0c;小明每次爬山或下山高度只能相差k及k以內&#xff0c;每次只能上下左右一個方向上移動一格&#xff0c;小明從左上角(0,0)位置出發 輸入描述 第一行…

Android:使用OkHttp

1、權限&#xff1a; <uses-permission android:name"android.permission.INTERNET" /> implementation com.squareup.okhttp3:okhttp:3.4.1 2、GET&#xff1a; new XXXTask ().execute("http://192.168.191.128:9000/xx");private class XXXTask…

Vue3+Element Plus動態表格列寬設置

在 Vue3 Element Plus 中實現動態設置表格列寬&#xff0c;可以通過以下幾種方式實現&#xff1a; 方法 1&#xff1a;動態綁定 width 屬性&#xff08;推薦&#xff09; vue 復制 下載 <template><el-table :data"tableData" style"width: 100%…

【JVM目前使用過的參數總結】

JVM參數總結 筆記記錄 JVM-棧相關JVM-方法區(元空間)相關JVM-堆相關 JVM-棧相關 .-XX:ThreadStackSize1M -Xss1m 上面的簡寫形式【設置棧的大小】 JVM-方法區(元空間)相關 -XX:MaxMetaspaceSize10m 【設置最大元空間大小】 JVM-堆相關 -XX:MaxHeapSize10m -Xmx10m 上面的簡寫形…