單例模式之懶漢式

文章目錄

  • 單例模式(懶漢式)
    • 代碼
      • 懶漢式(線程不安全)
      • 懶漢式(線程安全,加鎖)
      • 雙重檢查鎖(線程安全,推薦)

單例模式(懶漢式)

懶漢式是符合懶加載的模式,但是會存在線程并發的問題發生,所以還需要一種解決線程并發的機制,比如:加鎖等

單例模式懶漢式主要的構成是如下

  • 單例類
  • 私有化構造函數(防止實例化)
  • 私有化變量
  • 公共靜態獲得實例的方法(在調用這個方法的時候才進行實例化)
  • 解決線程并發的機制

代碼

懶漢式(線程不安全)

package singleton.type3;/***** @author: Hui**/
public class SingletonTest3 {public static void main(String[] args) {Singleton singleton =   Singleton.getInstance();Singleton singleton1 =   Singleton.getInstance();System.out.println(singleton == singleton1);System.out.println(singleton.hashCode());System.out.println(singleton1.hashCode());}
}class Singleton{//1.構造器私有化private Singleton(){}//2.靜態實例私有化private static Singleton singleton;//3.提供實例的靜態方法public static Singleton getInstance(){if (singleton == null){singleton = new Singleton();}return singleton;}
}

以上方法雖然實現了懶加載,但是線程不安全,在實際開發情況下不能使用。

因為以上代碼會出現線程不安全的情況,那么我們如何保證線程安全呢?最簡單的就是加鎖,在提供實例的靜態方法中加鎖,就可以保證線程安全了。

懶漢式(線程安全,加鎖)

package singleton.type4;
/*** @author: Hui**/
public class SingletonTest4 {public static void main(String[] args) {System.out.println("線程安全,加鎖");Singleton singleton = Singleton.getInstance();Singleton singleton1 = Singleton.getInstance();System.out.println(singleton == singleton1);System.out.println(singleton.hashCode());System.out.println(singleton1.hashCode());}
}class Singleton {//1.構造器私有化private Singleton() {}//2.靜態實例私有化private static Singleton singleton;//3.提供實例的靜態方法public static synchronized Singleton getInstance() {if (singleton == null) {singleton = new Singleton();}return singleton;}
}

雖然解決了線程安全問題,但是性能太差了,每一次調用實例都需要進入同步方法,其實我們創建實例的時候保持同步就可以了。這個方法因為性能比較差,開發過程中不建議使用。

那上述鎖的是一個方法,我們可不可以將鎖的顆度降低,鎖住一個代碼塊呢?

代碼如下

  //3.提供實例的靜態方法public static synchronized Singleton getInstance() {if (singleton == null) {synchronized(Singleton){singleton = new Singleton();}}return singleton;}

像以上方法是不是就實現了提高性能呢?是的,但是也出現了線程不安全的問題,比如有多個線程進入 if (singleton == null) 那么是不是會有多個線程進行創建對象。所以為了減少顆粒度又要保證線程安全,我們可以使用雙層檢查鎖來完成!!!

  //3.提供實例的靜態方法public static synchronized Singleton getInstance() {if (singleton == null) {synchronized(Singleton.class){if (singleton == null){singleton = new Singleton();} }}return singleton;}

我們只需要在加鎖的代碼塊中再進行一次空判斷,就可以很好的解決并發問題了,當一個線程進入的時候,先判斷是否為空,為空才創建對象,不為空直接返回。

雙重檢查鎖很好的解決線程不安全問題,并且達到性能的提升。

在實際開發中推薦使用

雙重檢查鎖(線程安全,推薦)

package singleton.type5;/*** @author: Hui**/
public class SingletonTest5 {public static void main(String[] args) {System.out.println("雙重檢查鎖,推薦使用");Singleton singleton = Singleton.getInstance();Singleton singleton1 = Singleton.getInstance();System.out.println(singleton == singleton1);System.out.println(singleton.hashCode());System.out.println(singleton1.hashCode());}
}class Singleton {//1.私有化構造器private Singleton() {}//2.聲明靜態變量,volatile 保證內存的可見性private static volatile Singleton instance;public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {//雙重檢查鎖if (instance == null) {instance = new Singleton();}}}return instance;}}

注意變量一定要使用 volatile 修飾,保證變量內存修改時的可見性。

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

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

相關文章

xxl-job集成SpringBoot

安裝xxl-job客戶端一般有很多方式,我這里給大家提供兩種安裝方式,包含里面的各項配置等等。 前期需要準備好MySQL數據庫。復制SQL到數據庫里面。 # # XXL-JOB v2.4.2-SNAPSHOT # Copyright (c) 2015-present, xuxueli.CREATE database if NOT EXISTS x…

項目機會:4萬平:智能倉,AGV,穿梭車,AMR,WMS,提升機,機器人……

導語 大家好,我是社長,老K。專注分享智能制造和智能倉儲物流等內容。 如下為近期國內智能倉儲物流相關項目的公開信息線索,這些項目具體信息會發布到知識星球,請感興趣的球友先人一步到知識星球【智能倉儲物流技術研習社】自行下載…

《SoC設計方法與實現》:全面掌握系統芯片設計精髓(可下載)

SoC(System on Chip,系統級芯片)設計是一項復雜而精細的工程活動,它涉及到將一個完整的電子系統的所有組件集成到一個單一的芯片上,包括處理器核心、內存、輸入/輸出端口以及可能的其他功能模塊。這種集成不僅要求設計…

oracle存儲結構-----邏輯存儲結構(表空間、段、區、塊)

文章目錄 oracle存儲結構圖(邏輯存儲物理存儲)oracle邏輯存儲結構圖邏輯存儲結構、表空間、段、區、數據塊的關系:1、數據 塊(block)---邏輯存儲最小單位2、 數據區(extent)--存儲空間分配和回收…

【AutoencoderKL】基于stable-diffusion-v1.4的vae對圖像重構

模型地址:https://huggingface.co/CompVis/stable-diffusion-v1-4/tree/main/vae 主要參考:Using-Stable-Diffusion-VAE-to-encode-satellite-images sd1.4 vae 下載到本地 from diffusers import AutoencoderKL from PIL import Image import torch import to…

電腦經常黑屏

情況簡述: 電腦經常突然黑屏,并且鼠標還能看到并且可操控 你是不是試過以下方法: 更換顯卡驅動版本?重置BIOS?重裝系統?全網找千篇一律沒啥用的教程? 這個標志熟悉吧,看看你的電腦里是否安裝了火絨,如果裝了繼續…

MySQL在Windows系統上的詳細安裝指南

一、準備工作 1. 確定MySQL版本 訪問MySQL官方網站:首先,你需要訪問MySQL的官方網站(MySQL),或者更具體地,訪問MySQL的下載頁面(MySQL :: Download MySQL Community Server)。 選擇…

Linux運維:mysql主從復制原理及實驗

當一臺數據庫服務器出現負載的情況下,需要擴展服務器服務器性能擴展方式有向上擴展,垂直擴展。向外擴展,橫向擴展。通俗的講垂直擴展是將一臺服務器擴展為性能更強的服務器。橫向擴展是增加幾臺服務器。 主從復制好比存了1000塊錢在主上&…

Android14之獲取包名/類名/服務名(二百二十三)

簡介: CSDN博客專家,專注Android/Linux系統,分享多mic語音方案、音視頻、編解碼等技術,與大家一起成長! 優質專欄:Audio工程師進階系列【原創干貨持續更新中……】🚀 優質專欄:多媒…

深度學習-梯度下降算法-NLP(五)

梯度下降算法 深度學習中梯度下降算法簡介找極小值問題數學上求最小值梯度梯度下降算法 找極小值問題在深度學習流程中深度學習整體流程圖求解損失函數的目標權重的更新 深度學習中梯度下降算法簡介 找極小值問題 引子: 我們訓練一個人工智能模型,簡單…

磁致伸縮液位計原理和特點

工作原理 磁致伸縮液位計的工作原理基于磁性材料在外部磁場作用下的尺寸變化來進行液位測量。該液位計主要由電子變送器、浮球(浮子)、探測桿(測桿)三部分組成。在磁致伸縮液位計的傳感器測桿外配有一浮子,此浮子可以…

【SpringCloud應用框架】Nacos服務配置中心

第四章 Spring Cloud Alibaba Nacos之服務配置中心 文章目錄 一、基礎配置二、新建子項目1.pom文件2.YML配置3.啟動類4.業務類5.Nacos配置規則 三、Nacos平臺創建配置操作四、自動配置更新五、測試 一、基礎配置 Nacos不僅僅可以作為注冊中心來使用,同時它支持作為…

【環境準備】 Vue環境搭建

文章目錄 前言vue-cli 安裝創建項目3.0、以下3.0 、以上 前言 書接上回《NodeJs(壓縮包版本)安裝與配置》,安裝完了NodeJs,接下來就要配置vue的環境了。 vue-cli 安裝 安裝vue-cli輸入如下命令 #(安裝的是最新版) npm install …

觀察者模式(Observer Pattern)

觀察者模式(Observer Pattern) 定義 觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。別名&#xff1…

鼠標宏怎么設置?6款鼠標自動點擊器強推,游戲玩家專用!(2024全)

隨著電子游戲和日常應用的不斷發展,我們經常會遇到一些重復性的任務或操作。而在這種情況下,鼠標宏以其自動化的特點成為了許多玩家和使用者的利器之一。如果你正在尋找如何設置鼠標宏來簡化操作并提高效率,那么你來對地方了。在本文中&#…

【Java]認識泛型

包裝類 在Java中,由于基本類型不是繼承自Object,為了在泛型代碼中可以支持基本類型,Java給每個基本類型都對應了一個包裝類型。 除了 Integer 和 Character, 其余基本類型的包裝類都是首字母大寫。 泛型 泛型是在JDK1.5引入的…

ASAN排查程序中內存問題使用總結

簡介 谷歌有一系列Sanitizer工具,可用于排查程序中內存相關的問題。常用的Sanitizer工具包括: Address Sanitizer(ASan):用于檢測內存使用錯誤。Leak Sanitizer(LSan):用于檢測內存…

【9-2:RPC設計】

RPC 1. 基礎1.1 定義&特點1.2 具體實現框架1.3 應用場景2. RPC的關鍵技術點&一次調用rpc流程2.1 RPC流程流程兩個網絡模塊如何連接的呢?其它特性RPC優勢2.2 序列化技術序列化方式PRC如何選擇序列化框架考慮因素2.3 應用層的通信協議-http什么是IO操作系統的IO模型有哪…

數據結構第14節 加權圖

加權圖是在圖論中一種更為復雜的圖結構,它擴展了無向圖和有向圖的概念,通過給圖中的邊附加一個數值來表示邊的某種屬性,如成本、距離、容量或相似度等。這個數值被稱為邊的“權重”。 定義 加權圖可以被形式化地定義為一個三元組 ( G (V, …

Vortex GPGPU的硬件設計和代碼結構分析

文章目錄 前言一、GPGPU是什么?1.1 GPU和GPGPU之間的差異1.2 GPU和CPU之間的集成方式1.3 GPU包含什么(列舉和VMIPS向量體系結構的差異) 二、Vortex GPGPU是什么?2.1 Vortex GPGPU的技術邊界和驗證環境2.2 Vortex GPGPU的指令集設計…