摘要:餓漢模式線程安全,調(diào)用效率高,但是不能延時(shí)加載這樣做的好處是編寫簡單,但是無法做到延遲創(chuàng)建對(duì)象??紤]線程安全的寫法這種寫法考慮了線程安全,將對(duì)的判斷以及的部分使用進(jìn)行加鎖。如此即可從語義上保證這種單例模式寫法是線程安全的。
餓漢模式
線程安全,調(diào)用效率高,但是不能延時(shí)加載
public class ImageLoader{ private static ImageLoader instance = new ImageLoader; private ImageLoader(){} public static ImageLoader getInstance(){ return instance; } }
這樣做的好處是編寫簡單,但是無法做到延遲創(chuàng)建對(duì)象。但是我們很多時(shí)候都希望對(duì)象可以盡可能地延遲加載,從而減小負(fù)載,所以就需要下面的懶漢法:
懶漢模式public class Singleton { private static Singleton singleton = null; private Singleton(){} public static Singleton getSingleton() { if(singleton == null) singleton = new Singleton(); return singleton; } }
這種方法可以實(shí)現(xiàn)延時(shí)加載,但是有一個(gè)致命弱點(diǎn):線程不安全(可見性,有序性)。如果有兩條線程同時(shí)調(diào)用getSingleton()方法,就有很大可能導(dǎo)致重復(fù)創(chuàng)建對(duì)象。
考慮線程安全的寫法public class Singleton { private static volatile Singleton singleton = null; private Singleton(){} public static Singleton getSingleton(){ synchronized (Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } return singleton; } }
這種寫法考慮了線程安全,將對(duì)singleton的null判斷以及new的部分使用synchronized進(jìn)行加鎖。同時(shí),對(duì)singleton對(duì)象使用volatile關(guān)鍵字進(jìn)行限制,保證其對(duì)所有線程的可見性,并且禁止對(duì)其進(jìn)行指令重排序優(yōu)化。如此即可從語義上保證這種單例模式寫法是線程安全的。注意,這里說的是語義上,實(shí)際使用中還是存在小坑的,會(huì)在后文寫到。
public class Singleton { private static volatile Singleton singleton = null; private Singleton(){} public static Singleton getSingleton(){ if(singleton == null){ synchronized (Singleton.class){ if(singleton == null){ singleton = new Singleton(); } } } return singleton; } }
這種寫法被稱為“雙重檢查鎖”,顧名思義,就是在getSingleton()方法中,進(jìn)行兩次null檢查??此贫啻艘慌e,但實(shí)際上卻極大提升了并發(fā)度,進(jìn)而提升了性能。為什么可以提高并發(fā)度呢?
在單例中new的情況非常少,絕大多數(shù)都是可以并行的讀操作。因此在加鎖前多進(jìn)行一次null檢查就可以減少絕大多數(shù)的加鎖操作,執(zhí)行效率提高的目的也就達(dá)到了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77544.html
摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...
摘要:使用靜態(tài)類體現(xiàn)的是基于對(duì)象,而使用單例設(shè)計(jì)模式體現(xiàn)的是面向?qū)ο?。二編寫單例模式的代碼編寫單例模式的代碼其實(shí)很簡單,就分了三步將構(gòu)造函數(shù)私有化在類的內(nèi)部創(chuàng)建實(shí)例提供獲取唯一實(shí)例的方法餓漢式根據(jù)上面的步驟,我們就可以輕松完成創(chuàng)建單例對(duì)象了。 前言 只有光頭才能變強(qiáng) 回顧前面: 給女朋友講解什么是代理模式 包裝模式就是這么簡單啦 本來打算沒那么快更新的,這陣子在刷Spring的書籍。在看...
摘要:單例模式的懶漢實(shí)現(xiàn)線程安全通過設(shè)置同步方法,效率太低,整個(gè)方法被加鎖模擬在創(chuàng)建對(duì)象之前做一些準(zhǔn)備工作使用上面的測試類,測試結(jié)果可以看到,這種方式達(dá)到了線程安全??梢哉f這種方式是實(shí)現(xiàn)單例模式的最優(yōu)解。 1. 什么是單例模式 單例模式指的是在應(yīng)用整個(gè)生命周期內(nèi)只能存在一個(gè)實(shí)例。單例模式是一種被廣泛使用的設(shè)計(jì)模式。他有很多好處,能夠避免實(shí)例對(duì)象的重復(fù)創(chuàng)建,減少創(chuàng)建實(shí)例的系統(tǒng)開銷,節(jié)省內(nèi)存。 ...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
摘要:基礎(chǔ)問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關(guān)鍵字修飾符知識(shí)點(diǎn)總結(jié)必看篇中的關(guān)鍵字解析回調(diào)機(jī)制解讀抽象類與三大特征時(shí)間和時(shí)間戳的相互轉(zhuǎn)換為什么要使用內(nèi)部類對(duì)象鎖和類鎖的區(qū)別,,優(yōu)缺點(diǎn)及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎(chǔ)問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 901·2021-10-27 14:19
閱讀 1120·2021-10-15 09:42
閱讀 1545·2021-09-14 18:02
閱讀 753·2019-08-30 13:09
閱讀 3000·2019-08-29 15:08
閱讀 2101·2019-08-28 18:05
閱讀 964·2019-08-26 10:25
閱讀 2795·2019-08-23 16:28