摘要:基礎(chǔ)系列的與方法類(lèi)初始化順序線程池如何彈性伸縮的幾個(gè)要點(diǎn)的緩存什么場(chǎng)景下使用阻塞隊(duì)列的使用及模式中的序本文主要介紹的相關(guān)知識(shí)。典型的使用場(chǎng)景,作為,采用來(lái)做信號(hào)通知不采用的容易出錯(cuò)即模式,就是雙加鎖檢查模式。因而有了雙重檢測(cè)模式的應(yīng)用。
Java基礎(chǔ)系列
Java的hashcode與equals方法
Java類(lèi)初始化順序
ThreadPoolExecutor線程池如何彈性伸縮
HashMap的幾個(gè)要點(diǎn)
Integer的緩存
什么場(chǎng)景下使用阻塞隊(duì)列
volatile的使用及DCL模式
try-catch-finally中的return
序本文主要介紹volatile的相關(guān)知識(shí)。
volatile要點(diǎn)volatile 只保證變量的線程可見(jiàn)性,不保證變量的原子性(只對(duì)賦值起作用),另外一個(gè)作用是防止重排序。
volatile 典型的使用場(chǎng)景,作為boolean,采用while來(lái)做信號(hào)通知
不采用volatile的dcl容易出錯(cuò)(DCL即Double Check Locking模式,就是雙加鎖檢查模式。)
代碼實(shí)例單例的延遲加載實(shí)現(xiàn)
package cn.javass.dp.singleton.example2; /** * 懶漢式單例示例 */ public class Singleton { /** * 定義一個(gè)變量來(lái)存儲(chǔ)創(chuàng)建好的類(lèi)實(shí)例 */ private static Singleton uniqueInstance = null; /** * 私有化構(gòu)造方法,好在內(nèi)部控制創(chuàng)建實(shí)例的數(shù)目 */ private Singleton(){ // } /** * 定義一個(gè)方法來(lái)為客戶(hù)端提供類(lèi)實(shí)例 * @return 一個(gè)Singleton的實(shí)例 */ public static synchronized Singleton getInstance(){ //判斷存儲(chǔ)實(shí)例的變量是否有值 if(uniqueInstance == null){ //如果沒(méi)有,就創(chuàng)建一個(gè)類(lèi)實(shí)例,并把值賦值給存儲(chǔ)類(lèi)實(shí)例的變量 uniqueInstance = new Singleton(); } //如果有值,那就直接使用 return uniqueInstance; } }
上面的代碼雖然在多線程的情況是線程安全的,也確保了只有一個(gè)實(shí)例,但是在高并發(fā)的情況下,synchronized 關(guān)鍵字會(huì)使得性能下降。
因此,不用synchronized修飾此方法,改在保證實(shí)例化實(shí)例的時(shí)候只有一個(gè)線程執(zhí)行就可以了。因而有了雙重檢測(cè)模式的應(yīng)用。
假設(shè)線程A,B同時(shí)進(jìn)入該方法,都檢測(cè)到instance為null,然后假設(shè)A先占用了同步鎖,然后實(shí)例化對(duì)象,之后B也會(huì)占用同步鎖去實(shí)例化,因而這里需要再一次檢測(cè)實(shí)例時(shí)是否已經(jīng)被創(chuàng)建了,此為雙重檢測(cè)的來(lái)源。
package cn.javass.dp.singleton.example10; public class Singleton { /** * 對(duì)保存實(shí)例的變量添加volatile的修飾 */ private volatile static Singleton instance = null; private Singleton(){ } public static Singleton getInstance(){ //先檢查實(shí)例是否存在,如果不存在才進(jìn)入下面的同步塊 if(instance == null){ //同步塊,線程安全的創(chuàng)建實(shí)例 synchronized(Singleton.class){ //再次檢查實(shí)例是否存在,如果不存在才真的創(chuàng)建實(shí)例 if(instance == null){ instance = new Singleton(); } } } return instance; } }為什么使用volatile關(guān)鍵字 1、volatile能夠保證變量在多線程之間的可見(jiàn)性
即 JVM的volatile語(yǔ)義保證了一個(gè)線程更新了這個(gè)變量,其他線程再下次讀取的時(shí)候,回去刷新本地緩存
2、為什么在JDK5之前是不安全的在JDK5之前,java的內(nèi)存模型允許out-of-writer,具體如下:
(1)java的new不是原子的,具體在更細(xì)的層面還是有諸多步驟:
A、 分配新對(duì)象的內(nèi)存
B、調(diào)用類(lèi)的構(gòu)造器,初始化成員字段
C、 instance被賦為指向新的對(duì)象的引用。
說(shuō)白了,JDK5之前不能保證有volatile修飾的對(duì)象構(gòu)造內(nèi)部是有序的。
(2)線程A發(fā)現(xiàn)instance沒(méi)有被實(shí)例化,它獲得鎖,然后去實(shí)例化該對(duì)象,JVM容許在沒(méi)有完全實(shí)例化完成的時(shí)候,將實(shí)例的指針賦給這個(gè)instance變量,而此時(shí)instance==null就為false了,在初始化完成之前,線程B進(jìn)入此方法,發(fā)現(xiàn)instance不為空,認(rèn)為已經(jīng)初始化完成了,于是便使用了這個(gè)尚未完全初始化的實(shí)例對(duì)象,可能引起其他的異常。
64位long和double在JVM規(guī)范中Java內(nèi)存模型要求lock、unlock、read、load、assign、use、store、write這8個(gè)操作必須是原子的,但是對(duì)于64位的long和double來(lái)說(shuō),如果沒(méi)有被volatile修飾符修飾,那么可以不是原子的,注意是可以,即虛擬機(jī)在實(shí)現(xiàn)的時(shí)候可以選擇是否是原子操作。目前幾乎所有的商用虛擬機(jī)都將此實(shí)現(xiàn)為原子操作,因此不必每次用到它們都去加volatile修飾。
參考JVM并發(fā)機(jī)制的探討——內(nèi)存模型、內(nèi)存可見(jiàn)性和指令重排序
關(guān)于Java中的volatile型變量
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/65581.html
摘要:?jiǎn)卫J礁攀鰡卫J绞且环N對(duì)象創(chuàng)建模式,用于產(chǎn)生一個(gè)類(lèi)的具體事例。所以解決了線程安全問(wèn)題參考失效原因和解決方案中單例模式的缺陷及單例的正確寫(xiě)法懶漢式靜態(tài)內(nèi)部類(lèi)私有構(gòu)造器獲取單例的方法靜態(tài)內(nèi)部類(lèi)持有單例作為靜態(tài)屬性。 單例模式概述 單例模式是一種對(duì)象創(chuàng)建模式,用于產(chǎn)生一個(gè)類(lèi)的具體事例。使用單例模式可以確保整個(gè)系統(tǒng)中單例類(lèi)只產(chǎn)生一個(gè)實(shí)例。有下面兩大好處: 對(duì)于頻繁創(chuàng)建的對(duì)象,節(jié)省初第一...
摘要:雙重檢查鎖定以下稱(chēng)為已被廣泛當(dāng)做多線程環(huán)境下延遲初始化的一種高效手段。由于沒(méi)有對(duì)這些做出明確規(guī)定,很難說(shuō)是否有效??梢栽谥惺褂蔑@式的內(nèi)存屏障來(lái)使生效,但中并沒(méi)有這些屏障。如果改變鎖釋放的語(yǔ)義釋放時(shí)執(zhí)行一個(gè)雙向的內(nèi)存屏障將會(huì)帶來(lái)性能損失。 雙重檢查鎖定(以下稱(chēng)為DCL)已被廣泛當(dāng)做多線程環(huán)境下延遲初始化的一種高效手段。 showImg(http://segmentfault.com/i...
摘要:面試官要不你來(lái)手寫(xiě)下單例模式唄候選者單例模式一般會(huì)有好幾種寫(xiě)法候選者餓漢式簡(jiǎn)單懶漢式在方法聲明時(shí)加鎖雙重檢驗(yàn)加鎖進(jìn)階懶漢式靜態(tài)內(nèi)部類(lèi)優(yōu)雅懶漢式枚舉候選者所謂餓漢式指的就是還沒(méi)被用到,就直接初始化了對(duì)象。面試官:我看你的簡(jiǎn)歷寫(xiě)著熟悉常見(jiàn)的設(shè)計(jì)模式,要不你來(lái)簡(jiǎn)單聊聊你熟悉哪幾個(gè)吧?候選者:常見(jiàn)的工廠模式、代理模式、模板方法模式、責(zé)任鏈模式、單例模式、包裝設(shè)計(jì)模式、策略模式等都是有所了解的候選者:...
摘要:總結(jié)單例是運(yùn)用頻率很高的模式,因?yàn)榭蛻?hù)端沒(méi)有高并發(fā)的情況,選擇哪種方式并不會(huì)有太大的影響,出于效率考慮,推薦使用和靜態(tài)內(nèi)部類(lèi)實(shí)現(xiàn)單例模式。 單例模式介紹 單例模式是應(yīng)用最廣的模式之一,也可能是很多人唯一會(huì)使用的設(shè)計(jì)模式。在應(yīng)用單例模式時(shí),單例對(duì)象的類(lèi)必須保證只用一個(gè)實(shí)例存在。許多時(shí)候整個(gè)系統(tǒng)只需要一個(gè)全局對(duì)象,這樣有利于我么能協(xié)調(diào)整個(gè)系統(tǒng)整體的行為。 單例模式的使用場(chǎng)景 確保某個(gè)類(lèi)有且...
閱讀 3309·2023-04-26 02:40
閱讀 4661·2021-09-22 15:22
閱讀 1604·2021-09-22 10:02
閱讀 3492·2021-08-11 10:23
閱讀 1400·2019-08-30 15:55
閱讀 2504·2019-08-30 12:48
閱讀 595·2019-08-30 11:04
閱讀 715·2019-08-29 16:29