java單例模式之線程安全問題

單例的目的是為了保證運行時Singleton類只有唯一的一個實例,用于一些較大開銷的操作。

餓漢式(沒有線程安全問題):

由于使用static關鍵字進行了修飾,只能獲取到一個對象,從而達到了單例,并且在Singleton類初始化的時候就創建了對象,加載到了內存。

問題:在沒有使用這個對象的情況下就加載到內存是一種很大的浪費。

針對這種情況,有一種新的思想提出——延遲加載,也就是所謂的懶漢式。

懶漢式(存在線程安全問題):

?

這種方法在調用Singleton.getInstance()時才會創建對象,起到了延遲加載的作用。

問題:這樣的寫法在多個線程同時運行時,很有可能會產生多個實例對象,導致線程安全問題。

使用同步的方法解決這個問題,加上synchronized關鍵字,代碼如下:

  使用同步的代價是會在一定程度上降低程序的并發度,并且鎖定整個方法很消耗資源,原本采用延遲加載是為了節省資源,

所以,降低鎖的細粒度,代碼如下:

  但是這樣的寫法線程還是不安全,因為兩個線程可以同時進入if語句,線程A實例化對象返回之后,線程B不用經過判斷

能再實例化對象,并且返回另一個對象。為了解決這個問題,引入了臭名昭著的雙重鎖機制

上面的代碼看似解決了線程安全問題,也起到了延遲加載的作用,但是雙重鎖機制是沒有辦法工作的,有一篇文章解釋的非常

深刻:http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

在參考了一些資料,我認為雙重鎖機制之所以不能正常運行是因為,在new對象的時候,是有三個步驟的:分配內存空間,

初始化對象,然后將內存地址賦值給變量;在這么三個步驟中,極有可能會在操作上進行重排序,在重排序的情況下,還沒有初始化

對象,先將內存地址賦值給了變量(這種情況是可能存在的),當線程B進入時,發現變量不為null,就會直接返回這個實例,然而此時

可能拿到的是還沒有初始化完成的對象。所以雙重鎖機制是不提倡使用的。

在http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl文章中有提出,在新的內存模型下,實例字段使用volatile可以解

決雙重鎖檢查的問題,因為在新的內存模型下,volatile禁止了一些重排序,但是,同時,使用volatile的性能開銷也有所上升。

所以又提出一種新的模式——Initialization on Demand Holder.?這種方法使用內部類來做到延遲加載對象,在初始化這個內部類的時候,

JLS(Java Language Sepcification)會保證這個類的線程安全。代碼如下:

?

?

轉載于:https://www.cnblogs.com/ckgame/p/8328347.html

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

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

相關文章

路由協議和路由算法的不同

網絡上的主機、路由器通過路由選擇算法形成路由表,以確定發送分組的傳輸路徑。而路由選擇協議是路由器用來完成路由表建立和路由信息更新的通信協議。

2003 r2 64 iis php mysql_關于在win2003中,iis+php+mysql 配置的問題

IIS中配置PHP服務器(iis6.0php5.2.6mysql),步驟如下:1.我下的是php5.2.6_win32 ,下載后,解壓到d:\phpwin下面2.然后從其中找到一個叫php.ini-recommended的文件,更名為php.ini3.打開該文件,找到extension_dir ".…

448. Find All Numbers Disappeared in an Array 尋找有界數組[1,n]中的缺失數

[抄題]: Given an array of integers where 1 ≤ a[i] ≤ n (n size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this array. Could you do it with…

數據結構與算法--1.整型變量值互換

問題: 給定兩個整型變量a,b,在不使用其他變量的情況下,實現兩個變量值的交換。 """ 問題:整型變量值互換 給定兩個整型變量a,b,在不使用其他變量的情況下,實現兩個變量值的交換。 """ a 1234 b 5678 print("binar…

什么是真正的高清,你知道嗎?

摘要:高清,英文為“High Definition”,意思是“高分辨率”。一般所說的高清,有四個含義:高清電視,高清設備,高清格式,高清電影。 高清,英文為“High Definition”&#x…

oracle11g中SQL優化(SQL TUNING)新特性之SQL Plan Management(SPM)

1. 簡介 Oracle Database11gR1引進了SQL PlanManagement(簡稱SPM),一套允許DBA捕獲和保持任意SQL語句執行計劃最優的新工具,這樣,限制了刷新優化器統計數據,已有應用改變,甚至數據庫版本升級帶…

Linux基本命令+Makefile

1.linux下查看進程占用cpu的情況(top); 格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 主要參數 d:指定更新的間隔,以秒計算。q:沒有任何延遲的更新。如果使用者有超級用戶,則top命令將會以最高的優先…

數據結構與算法--2.數組的定位排序

問題: 給定一個數組A以及下標i,將數組元素進行調整,使得所有比A[i]小的元素排在前邊,接著是所有等于A[i]的元素,最后排列的是比A[i]大的元素 思路: 第一步:將數組分成兩部分,一部…

mysql語法題_mysql數據庫題語法練習

一、練習。導入下面sql執行語句/*數據導入:Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50624Source Host : localhostSource Database : sqlexamTarget Server Type : MySQLTarget Server Version …

ipv4的不足

v地址基本耗盡,這是當前最棘手的問題v路由表越來越大v功能不足,缺少對多媒體信息傳輸的支持v缺少對高速傳輸的支持v缺少對安全的支持v缺少對主機漫游的支持

OpenGL開發庫的詳細介紹

OpenGL開發庫的組成 開發基于OpenGL的應用程序&#xff0c;必須先了解OpenGL的庫函數。它采用C語言風格&#xff0c;提供大量的函數來進行圖形的處理和顯示。OpenGL庫函數的命名方式非常有規律。所有OpenGL函數采用了以下格式<庫前綴><根命令><可選的參數個數&g…

thinkphp5運行原理_ThinkPHP5.1~5.2全版本遠程代碼執行高危漏洞預警

漏洞綜述關于ThinkPHPThinkPHP是一個快速、兼容而且簡單的輕量級國產PHP開發框架&#xff0c;其借鑒了國外很多優秀的框架和模式&#xff0c;包括使用面向對象的開發結構和MVC模式&#xff0c;融合了Struts的思想和TagLib(標簽庫)、RoR的ORM映射和ActiveRecord模式等。該框架常…

ASP.NET MVC中controller和view相互傳值的方式

ASP.NET MVC中Controller向view傳值的方式&#xff1a; ViewBag、ViewData、TempData單個值的傳遞Json匿名類型ExpandoObjectCookieViewModel(向普通View頁面傳個Model對象、向強類型頁面傳一個Model對象、用一個ViewModel對象解決所有問題)ASP.NET MVC中view向Controller傳值的…

自定義SeekBar 實時顯示百分比進度

進度下方實時顯示百分比進度禁止掉了SeekBar的滑動事件 詳情 githus地址

數據結構與算法--3.字符串的旋轉

題目&#xff1a; A是含有n個元素的數組&#xff0c;如果可以申請到最大內存&#xff0c;那么把A從位置i開始旋轉是比較簡單的。例如&#xff1a;A:a,b,c,d,e.其中i3,旋轉后的字符串A為&#xff1a;d,e,a,b,c要求設計一個時間復雜度為O(n),空間復雜度為O(1)的算法&#xff0c;…

三網融合情況下,實時語音通信技術解決之道

隨著技術和標準的不斷成熟,伴隨著“三網合一”的大潮,VoIP可望成為下一代電信基礎設施結構的楊心,使未來各電信業務綜合統一在IP網絡上成為可能,導致數據的融合和未來電信市場的重組,并帶來新的經濟模式和價值鏈。 Internet在全世界范圍內的快速發展和語音信號處理技術的進步,促…

ipv6相對于ipv4的改進

v更大的地址空間&#xff1a;16字節&#xff0c;128位v首部的簡化&#xff1a;只有7個固定域&#xff0c;撤消了有關分段的域和校驗和域&#xff0c;以便更快地處理分組&#xff0c;提高路由器的吞吐量縮短延時。v更好地支持選項&#xff1a;選項是有次序的&#xff0c;以便路由…

輕量高效的開源JavaScript插件和庫 【轉】

圖片布局輪播圖彈出層音頻視頻編輯器字符串表單存儲動畫時間其它加載器構建工具測試包管理器CDN圖片 baguetteBox.js - 是一個簡單易用的響應式圖像燈箱效果腳本。demoLightgallery.js - 是一個功能齊全的JavaScript圖像燈箱插件。demoviewerjs - 是一個圖像預覽插件。democrop…

Linux內核中的常用宏container_of其實很簡單【轉】

轉自&#xff1a;http://blog.csdn.net/npy_lp/article/details/7010752 開發平臺&#xff1a;Ubuntu11.04 編 譯器&#xff1a;gcc version 4.5.2 (Ubuntu/Linaro4.5.2-8ubuntu4) Container_of在Linux內核中是一個常用的宏&#xff0c;用于從包含在某個結構中的指針獲得結構本…

mysql concat例子_MYSQL中CONCAT詳解

concat()函數1. 功能&#xff1a;返回結果為連接參數產生的字符串。如有任何一個參數為NULL &#xff0c;則返回值為 NULL。2. 語法concat(str1, str2,...)3. 例子案例一&#xff1a;mysql> select concat(蘋果,香蕉,梨子);------------------------------| CONCAT(蘋果,香蕉…