對單例模式的餓漢式、懶漢式的思考

目錄

  • 1 什么是單例模式?
    • 1.1 什么是餓漢式?
    • 1.2 什么是懶漢式?
  • 2 我對餓漢式的思考
  • 3 懶漢式
    • 3.1 解決懶漢式的線程安全問題
      • 3.1.1 加鎖:synchronized(synchronized修飾靜態方法)
      • 3.1.2 對“3.1.1”性能的改進

1 什么是單例模式?

  • 單例模式是指一個類在JVM中只有一個實例。

1.1 什么是餓漢式?

  • 在類加載的時候就創建好了實例。

1.2 什么是懶漢式?

  • 創建實例延遲到使用該實例前。

2 我對餓漢式的思考

  • 示例
public class LearnSingleton {private static LearnSingleton instance = new LearnSingleton();private LearnSingleton() {}public static LearnSingleton getInstance() {return instance;}
}
  • 當我們調用LearnSingleton.getInstance()時,會觸發LearnSingleton的加載。在類加載的準備階段,創建好了靜態變量表(此時instance對應的slot槽還為null),等到了初始化階段,開始執行clinit方法,會創建LearnSingleton的示例(執行了new LearnSingleton()語句)。類加載后,執行getInstance()方法,將單例返回給用戶。
    • 這么一看,上述寫法不也是懶漢式嗎?在使用時才創建實例啊。(雖然,這個實例也是在類加載時就創建好的)
  • 要想明白這到底是懶漢式,還是餓漢式,關鍵在于:
public class LearnSingleton {private static LearnSingleton instance = new LearnSingleton();private LearnSingleton() {}public static LearnSingleton getInstance() {return instance;}public static int add(int x, int y) {return x + y;}
}
  • 當用戶調用LearnSingleton.add(1, 2)時,在類加載過程中,就已經創建好了單例,但并未使用。因此,這不符合在需要時創建單例的定義。從這個例子,就能想明白了,這種寫法是餓漢式。
  • 徹底的餓漢式:
public class LearnSingleton {private static final LearnSingleton instance = new LearnSingleton();private LearnSingleton() {}public static LearnSingleton getInstance() {return instance;}
}
  • 只要這個類加載了,由于instance是常量,因此在類加載的準備階段就創建好了單例。這是徹底的餓漢式。可謂“餓瘋了”😃。
  • 餓漢式,是在類加載階段完成實例的創建,由JVM保證了線程安全。

3 懶漢式

  • 在調用時才創建對象,示例:
public class LearnLazySingleton {private static LearnLazySingleton instance;private LearnLazySingleton() {}// 存在線程安全問題。假設兩個線程同時調用該方法,那么可能導致創建2個LearnLazySingleton對象。public static LearnLazySingleton getInstance() {if (instance == null) {instance = new LearnLazySingleton();}return instance;}
}

3.1 解決懶漢式的線程安全問題

3.1.1 加鎖:synchronized(synchronized修飾靜態方法)

public class LearnLazySingleton {private static LearnLazySingleton instance;private LearnLazySingleton() {}public synchronized static LearnLazySingleton getInstance() {if (instance == null) {instance = new LearnLazySingleton();}return instance;}public synchronized static int add(int x, int y) {return x + y;}public static int sub(int x, int y) {return x - y;}
}
  • 當線程A先調用getInstance()方法的同時, 另一個線程B嘗試訪問add()方法,線程B會因為沒有LearnLazySingleton的class對象的鎖而等待。如果類中的其他方法不是synchronized的,它們就不會被鎖定,即線程C調用sub方法()就不會等待。
    • 本質是因為,在調用同步方法前,只有獲取鎖,才能進入臨界區。而如果不是臨界區,那就不會受影響。

3.1.2 對“3.1.1”性能的改進

  • 上面的寫法,有個非常難受的地方,例如,線程A已經調用getInstance()方法,創建好了單例。但線程B為了獲取單例,也不得不調用getInstance()方法(唯一獲取實例的入口),這時候就可能和線程C撞車,因為只要線程C調用add方法(),就可能讓線程B獲取單例時發生阻塞。
  • 改進:
public class LearnLazySingleton {private static LearnLazySingleton instance;private LearnLazySingleton() {}public static LearnLazySingleton getInstance() {if (instance == null) {synchronized (LearnLazySingleton.class) {// 這里一旦要在判斷下,否則,線程A和線程B在這里排隊進入臨界區,會導致創建多個實例。if (instance == null) {instance = new LearnLazySingleton();}}}return instance;}public synchronized static int add(int x, int y) {return x + y;}
}
  • 在創建單例前,仍然存在線程A和線程B爭搶著執行“instance = new LearnLazySingleton();”,也會影響線程C去調用add()方法。但一旦實例創建好后,instance不為null,線程們調用getInstance()方法就不會阻塞了。

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

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

相關文章

環形鏈表詳解(讓你徹底理解環形鏈表)

文章目錄 一.什么是環形鏈表?二.環形鏈表的例題(力扣) 三.環形鏈表的延伸問題 補充 一.什么是環形鏈表? 環形鏈表是一種特殊類型的鏈表數據結構,其最后一個節點的"下一個"指針指向鏈表中的某個節點&#xff…

Python 教學平臺,支持“多班教學”的課程授課方式|ModelWhale 版本更新

龍行龘龘、前程朤朤,ModelWhale 新一輪的版本更新,期待為大家帶來更優質的使用體驗。 本次更新中,ModelWhale 主要進行了以下功能迭代: 新增 課程(包括課件、作業、算力)按班級管理(團隊版? …

springcloud的搭建和封裝,已進行開源,相互學習代碼知識。

springcloud架構的統一父工程,(管理子模塊,管理依賴插件,依賴版本等) abillty:能力服務塊:存放一些非業務相關的微服務,比如網關,身份認證等 exce: 網關中的一些異常信息處理 gatewa…

基于Springboot的人事管理系統 (有報告)。Javaee項目,springboot項目。

演示視頻: 基于Springboot的人事管理系統 (有報告)。Javaee項目,springboot項目。 項目介紹: 采用M(model)V(view)C(controller)三層體系結構&am…

【Git】merge時報錯:refusing to merge unrelated histories

文章目錄 一、問題二、解決辦法1、將feature分支的東西追加到master分支中2、將feature里的東西直接覆蓋到master分支中 一、問題 今天將feature分支合并到master時報錯:refusing to merge unrelated histories(拒絕合并無關歷史) 報錯原因&…

一篇文章速通static關鍵字(JAVA)

目錄 1.原理——內存機制 1.1 修飾對象 1.2 lifecycle生命周期 2. 靜態屬性(類屬性)和實例屬性(對象屬性) 2.1 定義方式 2.2 調用方法 3. 靜態方法和屬性 3.1 在同一個類中 3.2 在不同類中 4.總結(關鍵&#x…

SQLSyntaxEProrException異常產生原因及解決方案

java.sq1.SQLSyntaxEProrException異常產生原因及解決方案 01 異常的發生場景 在我mybatis-plus寫了一個查詢接口后出現的問題 java.sq1.SQLSyntaxEProrException日志報錯的意思是sql語法問題 02 異常的產生及其原因 我最開始又認為是MySQL數據庫表設計的問題&#xff0c…

ROS2從入門到精通:理論與實戰

ROS是什么? 隨著人工智能技術的飛速發展與進步,機器人的智能化已經成為現代機器人發展的終極目標。機器人發展的速度在不斷提升,應用范圍也在不斷拓展,例如自動駕駛、移動機器人、操作機器人、信息機器人等。機器人系統是很多復雜…

外貿福利 PHP源碼 WhatsApp 營銷 - 批量發件人、聊天、機器人、SaaS 搭建

WhatsApp 營銷工具對于外貿人員來說至關重要。隨著全球貿易的不斷發展,WhatsApp已成為了許多國際貿易商之間溝通的首選工具之一。通過利用WhatsApp營銷工具,外貿人員可以輕松地與客戶建立聯系,傳遞產品信息,進行價格談判&#xff…

Revit-二開之東西南北立面FilledRegion的CurveLoop計算-(4)

東西南北FilledRegion的CurveLoop計算 上一篇以東立面視圖為例創建FilledRegion,接下來我們將立面視圖創建FilledRegion的CurveLoop匯總一下。 上圖是對四個立面坐標系間的繪制方便我們計算FilledRegion的CurveLoop。 東立面CurveLoop計算 private CurveLoop GetEastCurveL…

3.1網安學習第三階段第一周回顧(個人學習記錄使用)

本周重點 ①HTML/JavaScript/CSS ②PHP ③正則表達式/文件上傳/文件讀寫 ④AJAX不跳轉提交 ⑤ OOP面向對象編程 本周主要內容 DAY1 HTML/JavaScript/CSS ①HTML 一、基本結構 <HTML> <head> //頭部內容 <title>網頁標題</title> </head&…

內網滲透-DC-9靶機滲透

攻擊機&#xff1a;kali 192.168.236.137 目標機&#xff1a;dc-9 192.168.236.138 一、信息收集 1.使用arp-scan -l和nmap進行主機發現和端口信息收集 nmap -sS -T5 --min-rate 10000 192.168.236.138 -sC -p- 發現22端口被阻塞 2.whatweb收集一下cms指紋信息 what http…

Vue開發實例(七)Axios的安裝與使用

說明&#xff1a; 如果只是在前端&#xff0c;axios常常需要結合mockjs使用&#xff0c;如果是前后端分離&#xff0c;就需要調用對應的接口&#xff0c;獲取參數&#xff0c;傳遞參數&#xff1b;由于此文章只涉及前端&#xff0c;所以我們需要結合mockjs使用&#xff1b;由于…

《熱辣滾燙》:用堅持不懈開啟逆境中的職場出路

"你只活一次&#xff0c;所以被嘲笑也沒有關系&#xff0c;想哭也沒有關系&#xff0c;失敗更沒有關系。" “人生就像一場拳擊賽&#xff0c;你站不起來&#xff0c;就永遠不知道自己有多強” “命運只負責洗牌&#xff0c;出牌的永遠是自己。” 在今年的賀歲檔電影市…

云時代【6】—— 鏡像 與 容器

云時代【6】—— 鏡像 與 容器 四、Docker&#xff08;三&#xff09;鏡像 與 容器1. 鏡像&#xff08;1&#xff09;定義&#xff08;2&#xff09;相關指令&#xff08;3&#xff09;實戰演習鏡像容器基本操作離線遷移鏡像鏡像的壓縮與共享 2. 容器&#xff08;1&#xff09;…

為什么模電這么難學?這是我見過最好的回答

大家好&#xff0c;我是磚一&#xff0c;有很多人抱怨模電難學&#xff0c;被譽為電子信息掛科率最高之一&#xff0c;下面聽我分析一下為啥模電這么難學&#xff1f; 01 理科的抽象思維 在高等教育體系中&#xff0c;模電是涉及半導體方向的第一門工程類課程&#xff0c;是一…

2024年3月5-7日年生物發酵裝備展-環科環保科技

參展企業介紹 山東環科環保科技有限公司,是一家集環保設備的設計、制造、安裝、服務及環境治理工程總承包于一體的企業。 公司長期專注于大氣、水、危固廢三大領域&#xff0c;以科技創造碧水藍天&#xff0c;為客戶提供環保解決方案。 以穩定的產品及服務質量、適用的技術、…

【環境搭建】linux centos7安裝mosquitto消息代理軟件操作步驟以及遇到問題日常記錄

最近需要用到mqtt&#xff0c; 選擇安裝mosquitto。由于安裝mosquitto花了我一點時間&#xff0c;簡單記錄下。安裝環境是linux centos7&#xff0c; 其他像windows、mac或者ubuntu 參考下 https://mosquitto.org/download/ 英文官網&#xff0c;或者別人寫的文章。 服務器…

微型世界:嵌入式科技的無限可能

微型世界&#xff1a;嵌入式科技的無限可能 1. 嵌入式科技的定義與特點 定義&#xff1a;嵌入式科技是一種特殊的計算機系統&#xff0c;通常用于特定的應用領域&#xff0c;如智能手機、智能家居設備等。特點&#xff1a;小巧、低功耗、高效率、實時性強、可靠性高、成本較低…

洛谷題單_搜索

P1219 [USACO1.5] 八皇后 Checker Challenge - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) #include <bits/stdc.h> using namespace std; const int N14; int n,ans0; int a[N][N]{},vis[N][N]{}; vector<int>rcd(n1); void dfs(int dep){if(depn1){if(ans<…