單例模式

1 簡介


單例模式是一種對象創(chuàng)建型模式静稻。單例模式保證一個類只有一個實例存在,并且同時提供一個全局的方法進(jìn)行進(jìn)行訪問該實例匈辱。

應(yīng)用場景

  • 在多個線程之間共享或?qū)ν粋€對象進(jìn)行操作時

  • 用作全局變量時

  • 大規(guī)模系統(tǒng)中為了提高性能振湾,減少對象的創(chuàng)建,節(jié)省創(chuàng)建時間

2 幾種實現(xiàn)方式


2.1 餓漢式

所謂餓漢式亡脸,就是不管三七二十一押搪,一上來就開干。不管你需不需要創(chuàng)建某個對象浅碾,只要在加載類的時候就創(chuàng)建大州。

我要吃吃吃吃

** - 實現(xiàn)方式**

實體類:Person.class

public class Person {
    private String name;
    private Integer age;
    <!-在Person被加載的時候Person對象就被創(chuàng)建-!>
    private static Person person = new Person();
<!--使用private ,防止用戶利用空參構(gòu)造器進(jìn)行實例化--!>
    private Person(){
        
    }
    public static Person getPerson(){
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

MainClass.class

public class MainClass {
    public static void main(String[] args) {
        Person person = Person.getPerson();
        person.setAge(20);
        person.setName("HAH");
        System.out.println(person.getName());
    }
}

在類加載時就實例化對象垂谢,這樣可以保證該對象的唯一性厦画,是線程安全的,但是相對的效率可能會降低滥朱,因為用戶也許就不需要實例化該對象根暑。

2.2 懶漢式

所謂懶漢式,顧名思義徙邻,就是用到的時候在創(chuàng)建购裙。也就是說,在類加載的時候不會實例化對象鹃栽,只有當(dāng)用戶真正的要創(chuàng)建對象的時候再調(diào)用方法實例化對象躏率。


哪位濕兄可以幫我蓋下被子QAQ

- 實現(xiàn)方式

Peison.class

public class Person {
    private String name;
    private Integer age;
    <!--類加載時不會實例化對象--!>
    private static Person person = null;
    private Person(){
        
    }
<!-用戶第一次調(diào)用getPerson時會創(chuàng)建對象,以后都不需要創(chuàng)建-!>
    public static Person getPerson(){
        if(person == null){
            person = new Person();
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }   
}

可見民鼓,使用懶漢式可以提高程序的靈活性薇芝。但是這樣也存在一個很大的缺陷。當(dāng)?shù)谝淮握{(diào)用getPerson( )方法時有多個線程同時訪問時丰嘉,那么就會出現(xiàn)線程同步問題夯到。所以的我們需要在方法上加上synchronized防止多個線程同時訪問。

** - 改進(jìn)**

Person.class

public class Person {
    private String name;
    private Integer age;
    
    private static Person person = null;
    private Person(){
        
    }
<!-在方法上加上synchronized保證當(dāng)前方法同一時間點只能有一個線程訪問-!>
    public static synchronized Person getPerson(){
        if(person == null){
            person = new Person();
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

在給getPerson( )方法上加上synchronized可以避免多個線程第一次同時訪問實例化多個對象饮亏,但是這樣在方法上加上synchronized會大大的降低程序的效率耍贾,因為只有第一次調(diào)用getPerson( )方法時才會發(fā)生線程問題阅爽,而第二次及以后調(diào)用均不會發(fā)生線程問題,這樣當(dāng)有一個線程調(diào)用getPerson( )方法時荐开,其它線程都將被阻塞付翁,直到調(diào)用方法的線程調(diào)用完畢。

2.3 雙重檢查

雙重檢查既是在懶漢式的改進(jìn)基礎(chǔ)上進(jìn)行改進(jìn)晃听,對實例化對象的代碼加鎖并加以判斷百侧,從而實現(xiàn)線程安全并且和懶漢式相比效率也大大提高。

- 具體實現(xiàn)

Person.class

public class Person {
    private String name;
    private Integer age;
    
    private static Person person = null;
    private Person(){
        
    }
    public static  Person getPerson(){
        if(person == null){                               (1
<!--將實例化對象的代碼加鎖--!>
            synchronized(Person.class){      (2
<!-防止第一次調(diào)用getPerson方法時多個線程同時進(jìn)入 (1能扒,當(dāng)?shù)谝痪€程創(chuàng)建完對象釋放鎖后佣渴,
后面的線程獲得鎖多次創(chuàng)建對象-!>
                if(person == null){
                    person = new Person();
                }
            }
            
        }
        return person;
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    
}

3 三種實現(xiàn)方式的比較


  • 餓漢式和雙重檢查是線程安全的,而未改進(jìn)的懶漢式不是線程安全的初斑。

  • 改進(jìn)后的懶漢式效率比較低辛润,因為給方法加上了synchronized,導(dǎo)致了同一時刻只能有一個線程訪問該方法见秤,造成其它線程堵塞砂竖。

  • 雙重檢查相對于餓漢式來說靈活性更高,只有用戶用到該對象的時候才會實例化秦叛,相對于懶漢式效率更高晦溪,用戶只有第一次訪問該瀑粥,方法才會進(jìn)入鎖挣跋,其它線程可能會堵塞,但是以后每次方法都可以并發(fā)狞换,線程不會再被阻塞避咆。

最近剛學(xué)設(shè)計模式,哪理解錯了修噪,望各位濕兄大佬多多指正

上一篇:抽象工廠模式
下一篇:原型模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末查库,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子黄琼,更是在濱河造成了極大的恐慌樊销,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脏款,死亡現(xiàn)場離奇詭異围苫,居然都是意外死亡,警方通過查閱死者的電腦和手機撤师,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門私蕾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智袭,“玉大人,你說我怎么就攤上這事膝擂。” “怎么了踱讨?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我铡羡,道長,這世上最難降的妖魔是什么嚎研? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任蓖墅,我火速辦了婚禮,結(jié)果婚禮上临扮,老公的妹妹穿的比我還像新娘论矾。我一直安慰自己,他們只是感情好杆勇,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布贪壳。 她就那樣靜靜地躺著,像睡著了一般蚜退。 火紅的嫁衣襯著肌膚如雪闰靴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天钻注,我揣著相機與錄音蚂且,去河邊找鬼。 笑死幅恋,一個胖子當(dāng)著我的面吹牛杏死,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捆交,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼淑翼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了品追?” 一聲冷哼從身側(cè)響起玄括,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肉瓦,沒想到半個月后遭京,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡泞莉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年哪雕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戒财。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡热监,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饮寞,到底是詐尸還是另有隱情孝扛,我是刑警寧澤列吼,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站苦始,受9級特大地震影響寞钥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陌选,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一理郑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咨油,春花似錦您炉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至法瑟,卻和暖如春冀膝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背霎挟。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工窝剖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酥夭。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓赐纱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親采郎。 傳聞我的和親對象是個殘疾皇子千所,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容