設計模式之單例模式(Java)

單例模式實現方式:懶漢式、餓漢式、雙重檢查、枚舉、靜態內部類;

懶漢式:

/*** 懶漢式單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public class LazySingleton implements Serializable {private static LazySingleton lazySingleton=null;private LazySingleton(){}//特點:第一次調用才初始化,避免內存浪費。public synchronized static LazySingleton getInstance(){if(lazySingleton==null){lazySingleton=new LazySingleton();}return lazySingleton;}
}

餓漢式:

/**餓漢式單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public class HungrySingleton {static final HungrySingleton hungrySingleton=new HungrySingleton();private HungrySingleton(){}//特點:類加載時就初始化,線程安全public static HungrySingleton getInstance(){return hungrySingleton;}
}

雙重檢查:

和懶漢式的區別就是,鎖的范圍減小了,防止多線程場景下創建多個實例,所以又加了一層判斷。

/**雙重檢查單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public class DoubleCheckSingletion {private static DoubleCheckSingletion doubleCheckSingletion=null;private DoubleCheckSingletion(){}//特點:安全且在多線程情況下能保持高性能public static DoubleCheckSingletion getInstance(){if(doubleCheckSingletion==null){synchronized (DoubleCheckSingletion.class){if(doubleCheckSingletion==null){doubleCheckSingletion=new DoubleCheckSingletion();}}}return doubleCheckSingletion;}
}

枚舉:

/**枚舉形單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public enum EnumSingleton {INSTANCE;//特點:自動支持序列化機制,絕對防止多次實例化public static EnumSingleton getInstance(){return INSTANCE;}
}

靜態內部類:

/**靜態內部類單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public class StaticInnerClassSingleton {private static class InnerClass{private static StaticInnerClassSingleton staticInnerClassSingleton=new StaticInnerClassSingleton();}private StaticInnerClassSingleton(){}public static StaticInnerClassSingleton getInstance(){return InnerClass.staticInnerClassSingleton;}
}

序列化或反射破壞單列模式:

通過序列化反序列化或反射可以破壞除枚舉以外的其它實現方式:

LazySingleton instance = LazySingleton.getInstance();//序列化破壞單例模式ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singletion"));oos.writeObject(instance);ObjectInputStream ois = new ObjectInputStream(new FileInputStream("singletion"));LazySingleton instance2 = (LazySingleton) ois.readObject();System.out.println(instance);System.out.println(instance2);System.out.println(instance2==instance);

運行:

解決反序列化破壞單列模式

解決方法只需要在單例類里加上一個readResolve()方法即可,原因就是在反序列化的過程中,會檢測readResolve()方法是否存在,如果存在的話就會反射調用readResolve()這個方法。

private Object readResolve(){return lazySingleton;}

使用枚舉單例模式天然就可以防止序列化破壞單例模式:

 EnumSingleton instance = EnumSingleton.getInstance();ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singletion"));oos.writeObject(instance);ObjectInputStream ois = new ObjectInputStream(new FileInputStream("singletion"));EnumSingleton instance2 = (EnumSingleton) ois.readObject();System.out.println(instance);System.out.println(instance2);System.out.println(instance==instance2);

運行:

為什么?

  • 枚舉類的序列化保證單例: Java枚舉類型在序列化和反序列化時會被特殊處理。在序列化的過程中,只是將枚舉對象的名字(即枚舉常量的名字)寫入到序列化文件中;在反序列化的過程中,通過名字來獲取枚舉對象。這保證了在反序列化過程中無論如何都只會得到枚舉中定義的枚舉常量,而不會重新創建新的對象。因此,枚舉類型的單例模式在反序列化過程中也能保持單例的狀態,不會被破壞。

  • 禁止反射創建多個實例: 枚舉類型的單例模式天然地禁止了通過反射機制來創建多個實例。枚舉類型的構造器是私有的,并且編譯器會確保枚舉常量只能被實例化一次。如果嘗試使用反射來調用枚舉類型的私有構造器來創建新的實例,會拋出IllegalArgumentException異常,從而保證了單例的唯一性。

?

反射破壞單例模式:

/**反射破壞單例模式* @author: 小手WA涼* @create: 2024-07-06*/
public class BrokenSingletonTest2 {public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {LazySingleton instance = LazySingleton.getInstance();Class<LazySingleton> lazySingletonClass = LazySingleton.class;Constructor<LazySingleton> constructor = lazySingletonClass.getDeclaredConstructor();constructor.setAccessible(true);LazySingleton refInstance = constructor.newInstance();System.out.println(instance);System.out.println(refInstance);System.out.println(instance==refInstance);}
}

?運行:

枚舉天然也可以防止反射破壞單例模式:

        EnumSingleton instance = EnumSingleton.getInstance();Class<EnumSingleton> singletonClass = EnumSingleton.class;Constructor<EnumSingleton> constructor = singletonClass.getDeclaredConstructor(String.class,int.class);constructor.setAccessible(true);EnumSingleton refInstance = constructor.newInstance();System.out.println(instance);System.out.println(refInstance);System.out.println(instance==refInstance);

運行:

這也是為什么枚舉是實現單例模式最好的方式原因之一。

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

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

相關文章

對BSV區塊鏈的曼達拉網絡通俗易懂的解釋

??發表時間&#xff1a;2023年6月15日 BSV區塊鏈正在引入“曼達拉”升級&#xff0c;使BSV區塊鏈網絡的拓撲結構能夠適配Teranode&#xff0c;適配這個可以大幅擴容的節點軟件。BSV區塊鏈上曼達拉網絡的概念并不會改變整個系統的核心規則&#xff1b;相反&#xff0c;它能夠引…

為什么https比http更安全

讀完本文&#xff0c;希望你能明白&#xff1a; HTTP通信存在什么問題HTTPS如何改進HTTP存在那些問題HTTPS工作原理是什么 一、什么是HTTPS HTTPS是在HTTP上建立SSL加密層&#xff0c;并對傳輸數據進行加密&#xff0c;是HTTP協議的安全版。現在它被廣泛用于萬維網上安全敏感…

【qt】如何獲取本機的IP地址?

需要用到這個類QHostInfo和pro里面添加network模塊 用這個類的靜態函數forName()來獲取該主機名的信息 返回的就是這個類 這個QHostInfo類就包括主機的IP地址信息 用靜態函數addresses()來獲取 返回的是一個QHostAddress的容器 QList<QHostAddress>addrList hostIn…

Laravel隊列機制深度解析:異步任務處理的高效之道

Laravel隊列機制深度解析&#xff1a;異步任務處理的高效之道 Laravel的隊列系統是一個強大的工具&#xff0c;用于執行后臺任務和異步處理。它允許開發者將耗時的任務&#xff0c;如發送郵件、處理圖片等&#xff0c;放入隊列中&#xff0c;然后由后臺工作進程異步執行。本文…

Docker 鏡像移動或復制到另一臺服務器

在實際的開發和部署過程中&#xff0c;我們可能需要將 Docker 鏡像從一臺服務器移動或復制到另一臺服務器。本文將詳細介紹如何實現這一操作&#xff0c;幫助你更好地管理和遷移 Docker 鏡像。 一、使用 docker save 和 docker load 命令 docker save 和 docker load 是 Dock…

課題申報書中要用的思路圖(技術路線圖)30張,超高清!

最近在弄課題申報書的時候&#xff0c;需要畫“技術路線圖”&#xff1b;和小伙伴們探討才發現很多人居然不會畫這種圖&#xff0c;還有很多人在Word里面一點一點拼湊…… 我給大家收集了網上非常熱門的30張“技術路線圖”&#xff0c;但網上流傳的都太模糊了&#xff0c;想看…

KBPC3506-ASEMI儲能專用整流橋KBPC3506

編輯&#xff1a;ll KBPC3506-ASEMI儲能專用整流橋KBPC3506 型號&#xff1a;KBPC3506 品牌&#xff1a;ASEMI 封裝&#xff1a;KBPC-4 正向電流&#xff08;Id&#xff09;&#xff1a;35A 反向耐壓&#xff08;VRRM&#xff09;&#xff1a;600V 正向浪涌電流&#xf…

基于RK3588的8路攝像頭實時全景拼接

基于RK3588的8路攝像頭實時全景拼接 輸入&#xff1a;2路csi轉8路mpi的ahd攝像頭&#xff0c;分辨率1920 * 1080 8路拼接結果&#xff1a; 6路拼接結果&#xff1a; UI界面&#xff1a; UI節目設計原理

SpringBoot新手快速入門系列教程一:window上編程環境安裝和配置

首先編譯器&#xff0c;建議各位不要去嘗試AndroidStudio和VisualStudio來做SpringBoot項目。乖乖的直接下載最新版即可 https://www.jetbrains.com.cn/idea/ 當然這是一個收費的IDE&#xff0c;想要便宜可以想辦法去某寶買授權&#xff0c;僅供學習參考用&#xff01;賺了錢…

Spring Boot中的多租戶架構實現

Spring Boot中的多租戶架構實現 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 一、引言 隨著云計算和SaaS&#xff08;軟件即服務&#xff09;模式的流行&a…

Matlab中collectPlaneWave函數的應用

查看文檔如下&#xff1a; 可以看出最多5個參數&#xff0c;分別是陣列對象&#xff0c;信號幅度&#xff0c;入射角度&#xff0c;信號頻率&#xff0c;光速。 在下面的代碼中&#xff0c;我們先創建一個3陣元的陣列&#xff0c;位置為&#xff1a;&#xff08;-1,0,0&#x…

52-3 權限維持 - IFEO注入(鏡像劫持)

IFEO注入(映像劫持)介紹 IFEO(Image File Execution Options)位于Windows注冊表中的路徑為: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options IFEO最初設計用于為在默認系統環境下可能出現錯誤的程序提供特殊的調試和執…

MySQL 常見錯誤及解決方案

1. Too many connections 運行環境&#xff1a;Winows11、Phpstudy V8.1.1.3、MySQL 5.7.26 同一時間 MySQL 的連接數量有限制&#xff0c;當超過上限時將提示下面錯誤信息&#xff1a; 1040 - Too many connections 查看當前最大連接數 mysql> show variables like %max_…

Android實現獲取本機手機號碼

和上次獲取設備序列號一樣&#xff0c;仍然是通過無障礙服務實現&#xff0c;在之前的代碼基礎上做了更新。代碼和demo如下&#xff1a; package com.zwxuf.lib.devicehelper;import android.accessibilityservice.AccessibilityService; import android.app.Activity; import…

css 選擇器匯總

目錄 所有選擇器偽類選擇器 所有選擇器 選擇器用法id選擇器#myid類選擇器.myclassname標簽選擇器div,h1,p相鄰選擇器h1p子選擇器ul > li后代選擇器li a通配符選擇器*屬性選擇器a[rel“external”]偽類選擇器a:hover, li:nth-child 偽類選擇器 在CSS3中新增了一個結構偽類選…

Bpuzzle V1.2 支持任意圖片!BlueLife Puzzle (bPuzzle) 是一款簡單的游戲,通過按正確的順序滑動拼圖塊來玩

BlueLife Puzzle (bPuzzle) 是一款簡單的游戲&#xff0c;通過按正確的順序滑動拼圖塊來玩。將您選擇的圖像拖放到主窗口或使用文件菜單選擇默認圖像。如果圖片格式是 JPG&#xff0c;大小無關緊要&#xff0c;但如果是 Png&#xff0c;則應為 800600 像素&#xff0c;然后 bPu…

nginx配置嘗試

from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse, FileResponse, HTMLResponse import logging import os from datetime import datetime import uvicorn# 初始化日志 logging.basicConfig(filenamefile_server.lo…

詳細的講解一下網絡變壓器應用POE ,AT BT AF BF的概念,做電路連接指導分析

網絡變壓器在應用POE&#xff08;Power over Ethernet&#xff09;技術時&#xff0c;承擔著重要的角色。它不僅負責數據的傳輸&#xff0c;同時也為網絡設備提供電力。在IEEE 802.3標準中&#xff0c;定義了幾個與POE相關的標準&#xff0c;包括802.3af、802.3at、802.3bt等&a…

智慧景區解決方案PPT(89頁)

智慧景區解決方案摘要 解決方案概述智慧景區解決方案旨在利用現代信息技術解決景區管理機構面臨的保護與發展矛盾&#xff0c;推動服務職能轉變&#xff0c;促進旅游產業跨越式發展&#xff0c;實現旅游經營增長和管理成本優化。 宏觀政策背景國家旅游局發布的《“十三五”全國…

VideoAgent——使用大規模語言模型作為代理來理解長視頻

概述 論文地址&#xff1a;https://arxiv.org/pdf/2403.10517 本研究引入了一個新穎的基于代理的系統&#xff0c;名為 VideoAgent。該系統以大規模語言模型為核心&#xff0c;負責識別關鍵信息以回答問題和編輯視頻。VideoAgent 在具有挑戰性的 EgoSchema 和 NExT-QA 基準上進…