Java創建型模式---單例模式

單例模式基礎概念

單例模式是一種創建型設計模式,其核心思想是確保一個類僅有一個實例,并提供一個全局訪問點來獲取這個實例。在 Java 中實現單例模式主要有以下關鍵點:

  1. 私有構造函數?- 防止外部通過new關鍵字創建實例
  2. 靜態實例變量?- 類內部持有唯一實例的引用
  3. 靜態訪問方法?- 提供全局訪問該實例的入口

單例模式的幾種實現方式

1. 餓漢式(線程安全)

餓漢式是最簡單的實現方式,在類加載時就創建實例:

public class EagerSingleton {// 類加載時就初始化實例private static final EagerSingleton instance = new EagerSingleton();// 私有構造函數private EagerSingleton() {}// 靜態訪問方法public static EagerSingleton getInstance() {return instance;}
}

優點:實現簡單,線程安全
缺點:類加載時就創建實例,可能造成資源浪費

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

懶漢式在首次調用時才創建實例,但存在線程安全問題:

public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}// 非線程安全的獲取實例方法public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}

優點:延遲加載,避免資源浪費
缺點:多線程環境下可能創建多個實例

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

為了解決線程安全問題,可以對獲取實例的方法進行同步:

public class LazySingletonSynchronized {private static LazySingletonSynchronized instance;private LazySingletonSynchronized() {}// 同步方法,保證線程安全public static synchronized LazySingletonSynchronized getInstance() {if (instance == null) {instance = new LazySingletonSynchronized();}return instance;}
}

優點:線程安全,延遲加載
缺點:同步方法開銷大,影響性能

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

結合懶加載和性能優化的雙重檢查鎖定實現:

public class DoubleCheckedLockingSingleton {// 使用volatile關鍵字保證可見性和禁止指令重排序private static volatile DoubleCheckedLockingSingleton instance;private DoubleCheckedLockingSingleton() {}public static DoubleCheckedLockingSingleton getInstance() {// 第一次檢查,避免不必要的同步if (instance == null) {synchronized (DoubleCheckedLockingSingleton.class) {// 第二次檢查,確保在同步塊內沒有其他線程創建實例if (instance == null) {instance = new DoubleCheckedLockingSingleton();}}}return instance;}
}

優點:線程安全,延遲加載,性能優化
缺點:實現復雜,需要理解 volatile 關鍵字的作用

5. 靜態內部類(推薦)

利用 Java 靜態內部類的特性實現高效、線程安全的單例:

public class StaticInnerClassSingleton {private StaticInnerClassSingleton() {}// 靜態內部類,持有外部類的實例private static class SingletonHolder {private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();}public static StaticInnerClassSingleton getInstance() {return SingletonHolder.INSTANCE;}
}

優點:線程安全,延遲加載,實現簡單
缺點:無法傳遞參數

6. 枚舉(最佳實踐)

使用枚舉實現單例是最簡潔、最安全的方式:

public enum EnumSingleton {INSTANCE;// 可以添加實例方法public void doSomething() {System.out.println("Singleton method called");}
}

優點

  • 線程安全
  • 防止反序列化重新創建新的對象
  • 防止反射攻擊
  • 實現簡單

缺點:無法實現延遲加載

單例模式的應用場景

單例模式在以下場景中經常使用:

  1. 資源管理器?- 如數據庫連接池、文件系統
  2. 配置信息類?- 全局配置信息的讀取和管理
  3. 日志記錄器?- 統一的日志輸出管理
  4. GUI 組件?- 如窗口管理器、對話框等

注意事項

  1. 序列化問題:如果單例類實現了 Serializable 接口,需要添加 readResolve () 方法防止反序列化創建新實例
  2. 反射攻擊:私有構造函數可以被反射破壞,枚舉實現可以避免此問題
  3. 多線程環境:必須考慮線程安全問題,推薦使用靜態內部類或枚舉實現

單例模式雖然簡單,但在實際應用中需要根據具體場景選擇合適的實現方式,同時注意處理好各種邊界情況,確保單例的唯一性和安全性。

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

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

相關文章

詳解Kafka重平衡機制詳解

Kafka 的重平衡機制(Rebalance)是確保消費者組內成員動態變化(如新成員加入、現有成員退出或崩潰、訂閱主題分區數變化)時,分區所有權能合理、公平地重新分配的核心機制。其目標是保證所有分區都有消費者處理&#xff…

代碼詳細注釋:文件IO在用戶管理系統中的應用實踐:C語言實現用戶名查重與密碼確認與支持日志記錄的終端用戶認證解決方案的注冊登錄系統

代碼/* 作業增強版注冊登錄系統 - 帶日志和安全性增強功能 */ #include <stdio.h> // 標準輸入輸出函數(printf, scanf等) #include <stdlib.h> // 標準庫函數(exit, malloc等) #include <string.h> // 字符串處理函數(strcmp, strcspn等) #inc…

Go與JS無縫協作:Goja引擎實戰之錯誤處理最佳實踐

引言&#xff1a;當Go邂逅JavaScript 在現代軟件開發中&#xff0c;跨語言協作已成為提升效率的關鍵。想象一下&#xff1a;用Go的高性能處理核心邏輯&#xff0c;同時用JavaScript的靈活性實現動態規則——這不再是夢想。Goja&#xff0c;這個純Go語言實現的JavaScript引擎&am…

繼承與多態:面向對象編程的兩大支柱

引言&#xff1a;為什么必須掌握繼承與多態&#xff1f; 在Java開發中&#xff0c;繼承與多態是構建可擴展、易維護系統的基石&#xff1a; 繼承&#xff1a;實現代碼復用&#xff0c;建立清晰的類層次結構多態&#xff1a;提升代碼靈活性&#xff0c;實現"編寫一次&#…

2025使用VM虛擬機安裝配置Macos蘋果系統下Flutter開發環境保姆級教程--上篇

前言 我們在學習Flutter開發的過程中&#xff0c;永遠都跳不過去的一個問題就是如何在MAC下開發并打包Flutter工程項目&#xff0c;但MAC開發首先要解決的問題就是我們一般技術人員的電腦都是WINDOWS操作系統&#xff0c;專門配置一臺MAC的話成本又是不得不考慮的因素&#xf…

250708-Svelte項目從Debian遷移到無法聯網的RHEL全流程指南

&#x1f4cc; 背景 在 Debian 上使用以下命令創建了一個 Svelte 項目&#xff1a; npm install -g sv npx sv create my-svelte-demo cd my-svelte-demo npm install npm run dev現在需要將該項目遷移到一臺 無法聯網的 RHEL 9.4 服務器 上運行&#xff0c;出現如下報錯&…

力扣 hot100 Day39

118. 楊輝三角 給定一個非負整數 numRows&#xff0c;生成「楊輝三角」的前 numRows 行。 class Solution { public:vector<vector<int>> generate(int numRows) {vector<vector<int>> res(numRows);for (int i 0; i < numRows; i) {res[i].resi…

HuggingFists: 無代碼處理復雜PDF

有過使用LLM搭建RAG或其它類知識系統的朋友一定會對文檔數據的復雜多樣性有著深刻的理解。各行各業的磁盤中都沉睡了數年到數十年的各類文檔信息&#xff0c;包括&#xff1a;Doc、Docx、PPT、PDF、XLS、PNG、JPEG等各類格式。利用LLM激活這些數據價值的首要工作就是能夠正確的…

Vue 3 框架實現理念、架構與設計哲學深度解析

第一部分&#xff1a;Vue 3 的起源&#xff1a;架構演進與設計哲學 Vue 3 的誕生并非一次簡單的版本迭代&#xff0c;而是一場深刻的架構革命。它的出現是前端技術演進、應用規模擴張以及對更高性能和可維護性追求的必然結果。要全面理解 Vue 3 的各項實現理念&#xff0c;必須…

SQL Server使用存儲過程導出數據到Excel實現方式

在SQL Server數據庫管理中,存儲過程作為預編譯的T-SQL語句集合,能顯著提升數據操作效率與安全性。將數據導出到Excel的需求廣泛存在于報表生成、數據遷移等場景。本文詳細解析四種通過存儲過程實現數據導出的技術方案,涵蓋代碼實現、適用場景及優化策略,為不同業務需求提供…

OpenGL 2. 著色器

#include <glad/glad.h> #include <GLFW/glfw3.h> #include <iostream> #include <stdexcept>// 函數聲明 void framebuffer_size_callback(GLFWwindow* window, int width, int height); void processInput(GLFWwindow* window); void checkShaderCom…

【c++】容器擴容導致的類實例資源被錯誤釋放

BUG記錄 表現為新實例被存入前&#xff0c;容器內部的舊實例的析構被意外調用 因為 std::vector 在容量不足時&#xff0c;會自動擴容&#xff0c;把舊元素「搬」到新內存&#xff0c;然后析構舊內存上的那些對象。然后由于LKMotorController 類里沒有正確處理移動語義&#xf…

TypeScript 集成

下面&#xff0c;我們來系統的梳理關于 Vue TypeScript 深度集成 的基本知識點&#xff1a;一、TypeScript 與 Vue 集成概述 1.1 為什么需要 TypeScript 類型安全&#xff1a;編譯時類型檢查&#xff0c;減少運行時錯誤代碼智能&#xff1a;強大的IDE智能提示和自動補全可維護…

npm proxy

背景 前端項目下載依賴時經常會出現timeout的情況&#xff0c;此時有三種解決方案。 切換鏡像源。 適用于對依賴版本要求不嚴格的情況。延長超時時間。設置npm proxy。一些生產環境對依賴版本有著嚴格要求&#xff0c;并且指定了依賴的下載地址&#xff08;如下圖&#xff09;&…

TVS管工作原理是什么?主要的應用場景都有哪些?

什么是TVS管&#xff1f; TVS&#xff08;Transient Voltage Suppressors&#xff09;&#xff0c;即瞬態電壓抑制器&#xff0c;也被稱為雪崩擊穿二極管&#xff0c;是一種二極管形式的高效能保護器件&#xff0c;常用來防止端口瞬間的電壓沖擊造成后級電路的損壞。 TVS 有單…

分布式微服務系統架構第156集:JavaPlus技術文檔平臺日更-Java線程池使用指南

title: java線程池使用 author: 哪吒 date: 2023-06-15點擊勘誤issues&#xff0c;哪吒感謝大家的閱讀Java線程池使用指南1. 線程池基礎使用1.1 創建線程池的方式方式一&#xff1a;使用Executors工具類&#xff08;不推薦&#xff09;// 1. 固定大小線程池 ExecutorService fi…

【最新版】點大全能版v2.6.7.1 含匯付斗拱插件+uniapp前端

一.介紹V2全能版本、獨立版本全開源&#xff0c;含鏈動21&#xff0c;匯付斗拱?、排隊免單、推三返1 &#xff0c;扶持金&#xff0c;平級獎&#xff0c;團隊業績獎&#xff0c;酒店管理&#xff0c;約車&#xff0c;餐飲等眾多營銷功能&#xff0c;商城系統版本號為2.6.7.1&a…

Go語言高級面試必考:切片(slice)你真的掌握了嗎?

目錄 1. 切片是個啥?從數組到切片的靈魂進化 數組與切片的愛恨情仇 切片的內存結構:三巨頭共舞 切片的初始化方式:靈活到飛起 切片的“引用”特性:福也是禍 源碼初探:切片的誕生 2. 切片三劍客:len、cap 和底層數組的三角戀 len 和 cap 的微妙關系 切片共享的秘密…

monorepo + Turborepo --- 開發應用程序

目錄 配置開發任務 在 dev 之前運行設置任務 運行特定應用程序 使用終端 UI 與任務交互 監聽模式 watch 將 turbo watch 與持久任務一起使用 依賴感知的持久任務 沒有依賴感知的持久任務 緩存 任務輸出 局限性 在 Monorepo 中開發應用程序可以解鎖強大的工作流程&…

C#字符串相關庫函數運用梳理總結 + 正則表達式詳解

C# 字符串常用庫函數總結 &#x1f539; 1. 字符串比較 方法說明示例string.Equals()比較兩個字符串是否相等&#xff08;可忽略大小寫&#xff09;string.Equals("abc", "ABC", StringComparison.OrdinalIgnoreCase) / !判斷兩個字符串是否相等/不等&quo…