【Java单例模式】Java单例模式之懒汉模式线程安全
單例模式是設(shè)計(jì)模式中用得比較多的一種設(shè)計(jì)模式,它的主要優(yōu)點(diǎn)有:
1.訪問(wèn)受控,保證訪問(wèn)的是唯一的實(shí)例。
2.由于只有一個(gè)實(shí)例,所以節(jié)省資源。?
缺點(diǎn):
靈活性低,如果對(duì)象的應(yīng)用場(chǎng)景多變,則不適用單例模式。
?
1.如何實(shí)現(xiàn)單例模式?
1.1 懶漢模式(線程不安全)
想要實(shí)現(xiàn)單例,莫非就是要適用static關(guān)鍵字,如下聲明一個(gè)對(duì)象:
public class SingleTon {private static SingleTon singleTon = null;}這樣我們就得到了一個(gè)類型為SingleTon的靜態(tài)變量,接下來(lái),我們就要控制這個(gè)類,不能被任意的new出來(lái),這個(gè)就是實(shí)現(xiàn)了單例模式唯一性的根本,代碼如下:
public class SingleTon {private static SingleTon singleTon = null;//把構(gòu)造函數(shù)設(shè)置為private,防止被new實(shí)例化private SingleTon() {}public static SingleTon getInstance() {//每次調(diào)用SingleTon.getInstance()時(shí)返回的都是singleTon唯一對(duì)象if( singleTon == null ) {singleTon = new SingleTon();}return singleTon;}
?
這種模式的單例在非并發(fā)環(huán)境下是可靠的,我們知道,我們保證類是單例的代碼關(guān)鍵是
if(singleTon == null)
并且java中new是不具有原子性的(涉及到賦值問(wèn)題),所以,在并發(fā)環(huán)境下,是可能執(zhí)行了多次的new操作,造成實(shí)例非唯一性。
?
1.2如何解決?
為了解決問(wèn)題,首先就要明白問(wèn)題產(chǎn)生的原因:
上述懶漢產(chǎn)生多個(gè)實(shí)例造成單例失效的原因是在高并發(fā)環(huán)境下可能同時(shí)有2個(gè)或以上的線程訪問(wèn)getInstance()類方法,又因?yàn)閚ew操作不具有原子性,所以會(huì)導(dǎo)致產(chǎn)生2個(gè)實(shí)例的問(wèn)題。
?
因此,我們可以:
1.通過(guò)添加synchronized來(lái)修飾getInstance()方法,簡(jiǎn)單有效粗暴,但是往往暴力使用同步方法帶來(lái)的問(wèn)題都是一樣的,就是慘重的效率代價(jià)~
2.通過(guò)添加synchronized來(lái)同步部分代碼塊,并且通過(guò)volatile來(lái)防止指令重排,代碼如下:
public class SingleTon {private static SingleTon singleTon = null;private SingleTon() {}public static SingleTon getInstance() {if( singleTon == null ) {synchronized( SingleTon.class ) {if( singleTon == null ) {singleTon = new SingleTon();}}}return singleTon;}}上述方法就是傳說(shuō)中的DCL雙重檢查鎖定單例(JDK1.5之后的版本)
?
轉(zhuǎn)載于:https://www.cnblogs.com/dick159/p/6601086.html
總結(jié)
以上是生活随笔為你收集整理的【Java单例模式】Java单例模式之懒汉模式线程安全的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [Grid Layout] Place
- 下一篇: 浅谈数据库索引