【設計者模式】單例模式

文章目錄

  • 1、模式定義
  • 2、代碼實現
    • (1)雙重判空加鎖方式
      • 兩次判空的作用?
      • volatile 關鍵字的作用?
      • 構造函數私有?
    • (2)靜態內部類【推薦】
    • (3)Kotlin中的單例模式
      • lateinit 和 by lazy 的區別:
  • 3、優缺點
  • 4、參考資料

1、模式定義

  • 作為對象的創建模式,單例模式確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例。這個類稱為單例類。
  • 單例特別:(1)單例模式只能有一個實例。(2)單例類必須創建自己的唯一實例。(3)單例類必須向其他對象提供這一實例。

2、代碼實現

(1)雙重判空加鎖方式

public class Singlnton{private static volatile Singlnton instance;private Singlnton(){}public static Singlnton getInstance(){ // 1if(instance==null){ // 2synchronized(Singlnton.class){ // 3if(instance==null){ // 4instance = new Singlnton(); // 5}}}return instance;}}

兩次判空的作用?

  • 第一次:避免加鎖
  • 第二次:進行實例化

volatile 關鍵字的作用?

  • 雙重檢鎖單例模式在 CPU 的工作流,主要分為三步,1:分配內存對象空間。2:初始化對象。3:設置 instance 執行剛才分配的內存地址。注意 JVM 和 CPU 優化會指令重排,上面順序會變成 1 -> 3 -> 2,單線程環境下,此順序是沒有問題,2 和 3 前后沒有依賴性,但是在多線程情況下會有這種情況,當線程 A 在執行第 5 行代碼時,B 線程進來執行到第 2 行代碼。假設此時 A 執行的過程中發生了指令重排序,即先執行了 1 和 3,沒有執行 2。那么由于 A 線程執行了 3 導致 instance 指向了一段地址,所以 B 線程判斷 instance 不為 null,會直接跳到第 6 行并返回一個未初始化的對象,此時會產生空指針異常。volatile 能保持指令的有序性,能夠有效禁止指令重排序。
  • 注意:“Singlnton instance” 相當于分配內存對象空間;“new Singlnton()” 相當于初始化對象;"="相當于設置 instance 執行剛才分配的內存地址。

構造函數私有?

  • 無法通過調用該類的構造函數來實例化該類的對象,只有通過該類提供的靜態方法 getInstance 來得到該類的唯一實例

(2)靜態內部類【推薦】

public class Singlnton{private Singlnton(){}private static class SinglntonHolder{private static Singlnton INSTANCE = new Singlnton();}public static Singlnton getInstance(){return SinglntonHolder.INSTANCE;}}
  • 利用 JAVA 虛擬機加載類的特性實現延遲加載和線程安全
  • 由于靜態單例對象沒有作為 Singleton 的成員變量直接實例化,因此類加載時不會實例化 Singleton,第一次調用 getInstance() 時將加載內部類 SingletonHolder,在該內部類中定義了一個 static 類型的變量 INSTANCE,此時會首先初始化這個成員變量,由 Java 虛擬機來保證其線程安全性,確保該成員變量只能初始化一次。由于 getInstance() 方法沒有任何線程鎖定,因此其性能不會造成任何影響。
  • 類加載機制

(3)Kotlin中的單例模式

class Singlnton private constructor(){companion object{val instance : Singlnton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {Singlnton() }}}class Singlnton private constructor(){companion object{@Volatileprivate var instance: Singlnton? = nullfun getInstance(): Singlnton =instance ?: synchronized(this) {instance ?: Singlnton().also {instance = it}}}}

lateinit 和 by lazy 的區別:

  • lateinit 只能用于修飾變量 var,不能用于可空的屬性和 Java 的基本類型。
  • lateinit 可以在任何位置初始化并且可以初始化多次。
  • lazy() 只能用于修飾常量 val,并且 lazy() 是線程安全的。
  • lazy() 是一個函數,可以接受一個 Lambda 表達式作為參數,第一次調用時會執行 Lambda 表達式,以后調用該屬性會返回之前的結果。
  • lazy() 源碼分析

3、優缺點

  • 優點:
    • (1)在內存里只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例。
    • (2)避免對資源的多重占用。
  • 缺點:
    • (1)沒有接口,不能繼承,與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎么樣來實例化。
    • (2)濫用單例會帶來一些負面問題。如果實例化的對象長時間不被使用,系統會認定為垃圾而回收,這將導致共享對象狀態的改變
  • 注意事項:++不能使用反射調用私有構造器,這樣會實例化一個新的對象++
  • 如何避免反射創建新的單例對象

4、參考資料

  • 單例模式 Android 校招面試指南(只能在手機端打開)

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

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

相關文章

Matlab 最小二乘插值(曲線擬合)

文章目錄 一、簡介二、實現代碼三、實現效果參考資料一、簡介 在多項式插值時,當數據點個數較多時,插值會導致多項式曲線階數過高,帶來不穩定因素。因此我們可以通過固定冪基函數的最高次數 m(m < n),來對我們要擬合的曲線進行降階。之前的函數形式就可以變為: 二、實現…

spring Boot 報錯RedisConnectionFailureException

錯誤描述&#xff1a; 錯誤重點&#xff1a;&#xff08;圖片中藍色區域&#xff09; Unable to connect to Redis; 無法連接到Redis Unable to connect to 127.0.0.1 無法連接到本地服務器 所以&#xff0c;錯誤是本地服務器沒有連接上Redis所引起的 錯誤解析…

vue3中的父傳子,子傳父

在Vue 3中&#xff0c;父組件向子組件傳遞數據和子組件向父組件通信的方式與Vue 2非常相似&#xff0c;但Vue 3提供了Composition API和更多的響應式API&#xff0c;為組件間的通信提供了更多的可能性。下面是父傳子和子傳父的基本方法&#xff1a; ### 父組件傳遞數據給子組件…

【InternLM 實戰營筆記】使用SDK接口上傳模型到OpenXLab

概述 浦源內容平臺-模型中心的Python SDK旨在為開發人員提供編程方式來管理和操作模型中心平臺的功能&#xff0c;以便他們可以輕松地與模型中心進行交互和模型管理。通過Python SDK提供的推理接口&#xff0c;開發人員能夠高效地調用不同的模型&#xff0c;實現模型應用的開發…

遞歸實現排列型枚舉(c++題解)

題目描述 把 1~n 這 n(n<10) 個整數排成一行后隨機打亂順序&#xff0c;輸出所有可能的次序。 輸入格式 一個整數n。 輸出格式 按照從小到大的順序輸出所有方案&#xff0c;每行1個。 首先&#xff0c;同一行相鄰兩個數用一個空格隔開。其次&#xff0c;對于兩個不同的…

Linux——進程控制(二)進程等待

目錄 前言 一、進程等待 二、如何進行進程等待 1.wait 2.waitpid 2.1第二個參數 2.2第三個參數 3. 等待多個進程 三、為什么不用全局變量獲取子進程的退出信息 前言 前面我們花了大量的時間去學習進程的退出&#xff0c;退出并不難&#xff0c;但更深入的學習能為本…

048 異常

什么是異常 異常體系結構 異常的繼承關系 Error Exception 異常處理機制 try&#xff1a;用{}將可能產生異常的代碼包裹catch&#xff1a;與try搭配使用&#xff0c;捕獲try包裹代碼中拋出的異常并進行后續動作finally&#xff1a;跟在try后&#xff0c;在try和catch之后執行…

web3時事粥報

比特幣正成為更具有吸引力的通脹對沖工具 在通脹的宏觀經濟浪潮中&#xff0c;比特幣正逐漸嶄露頭角&#xff0c;成為那些渴望多元化投資組合的投資者眼中的璀璨明星。Kooner 預測&#xff0c;2024年&#xff0c;各種宏觀經濟挑戰可能進一步提升比特幣、黃金和白銀等資產的避險…

3月3日做題總結(C/C++真題)

第一題 參加位運算的數據其類型不能是&#xff08;&#xff09;。 A---int B---char C---float D---long int 正確答案&#xff1a;C 解析&#xff1a;無論是float&#xff0c;還是double&#xff0c;在內存中的存儲分為三部分&#xff1a;符號位、指數位、尾數位&#…

Google Dremel和parquet的復雜嵌套數據結構表征方法解析

轉載請注明出處。作者&#xff1a;archimekai 核心參考文獻&#xff1a; Dremel: Interactive Analysis of Web-Scale Datasets 文章目錄 引言復雜嵌套數據結構的無損表征問題Dremel論文中提出的表征方法parquet備注 引言 Dremel是Google的交互式分析系統。Google大量采用prot…

全量知識系統問題及SmartChat給出的答復 之17 知識系統中的兩個特權類(超類和欠類) :腳本和場景

Q.45 知識系統中的兩個特權類 &#xff1a;腳本和場景 知識系統中的兩個特權類&#xff08;也是集合論中兩個特權集合&#xff09;&#xff1a;腳本script和場景scene 。 一個$Demonstrate類型的腳本script&#xff1a; 表示“值val”&#xff08; 形式上是應用程序的實用工…

如何學習openfoam

學習OpenFOAM的詳細步驟、流程、學習網站、練習案例以及B站學習資源推薦如下&#xff1a; 一、詳細步驟和流程 安裝OpenFOAM&#xff1a;首先&#xff0c;你需要在你的計算機上安裝OpenFOAM。你可以從OpenFOAM的官方網站下載適合你的操作系統的安裝包&#xff0c;然后按照官方提…

搭建服務器及跨域處理

使用內置的模塊搭建服務器 自己電腦: 域名:localhost ip:127.0.0.1 http模塊搭建服務器 const http = require(http)// 創建一個http對應的服務器,每次改完服務器的代碼后都需要重新啟動下服務器 /*方式一: const server = http.createServer((request,response)=>{…

對簡單工廠模式、工廠方法模式的思考

目錄 1 背景1.1 題目描述1.2 輸入描述1.3 輸出描述1.4 輸入示例1.5 輸出示例 2 簡單工廠模式3 工廠方法模式4 思考4.1 改進工廠方法模式 1 背景 題目源自&#xff1a;【設計模式專題之工廠方法模式】2.積木工廠 1.1 題目描述 小明家有兩個工廠&#xff0c;一個用于生產圓形積木…

鐵路關基保護新規發布!鐵路軟件供應鏈安全洞察與治理思路

近日&#xff0c;國家鐵路局發布《鐵路關鍵信息基礎設施安全保護管理辦法》&#xff0c;《辦法》第十四條提到&#xff1a;“運營者應當加強鐵路關鍵信息基礎設施供應鏈安全保護&#xff0c;優先采購安全可信的網絡產品和服務。運營者采購網絡產品和服務&#xff0c;應當預判該…

Intel FPGA IP之LVDS SerDes IP學習

FPGA 視頻數據輸入輸出直通工程&#xff1a; 屏&#xff1a;13.2吋8bit色深&#xff0c;屏幕分辨率為1440*192060&#xff0c;具有兩個Port&#xff0c;每個Port有4個差分數據對與1個差分時鐘對&#xff0c;差分對均支持LVDS協議芯片&#xff1a;Cyclone V系列FPGA目的&#x…

標簽轉格式問題之——xml_2_txt.py

import xml.etree.ElementTree as ET#xml 是python自帶的package import osclasses[walnut]#寫自己的分類名 pre_dirF:/2023walnut/labels#xml文件所在文件夾 target_dirF:/2023walnut/yolo#想要存儲txt文件的文件夾 pathos.listdir(pre_dir)for path1 in path: # path1rC:\Use…

[變壓器故障診斷分類及預測】基于Elman神經網絡

課題名稱&#xff1a;基于Elman神經網絡的變壓器故障診斷分類及預測 版本日期&#xff1a;2024-02-10 運行方式&#xff1a;直接運行Elman0507.m文件 代碼獲取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 對變壓器油中溶解氣體進行分析是變壓…

Noise Conditional Score Networks(NCSN)學習

參考&#xff1a; [1] https://zhuanlan.zhihu.com/p/597490389 [2] https://www.zhangzhenhu.com/aigc/Score-Based_Generative_Models.html TOC 1 基于分數的生成模型1.1 簡介和動機1.2 Score Matching及其改進1.2.1 Score Matching1.2.2 Sliced score matching&#xff08;不…

XSS_lab(level1-level5)

level1 直接輸入頁面沒有發現輸入框&#xff0c;觀察url發現有傳參 嘗試修改傳參為&#xff1a;<script>alert(1)</script> 過啦&#xff01; level2 頁面中有輸入框&#xff0c;嘗試構建語句&#xff1a;<script>alert(1)</script>,傳輸后查看源代…