Java 設計模式---單例模式

來源:互聯網
上載者:User

標籤:

單例模式的寫法

1. 懶漢模式(線程不安全)

懶漢模式:顧名思義就是需要使用的時候才執行個體化;

線程不安全:設想兩個線程同時都運行到判斷instance是否等於null的if語句,並且instance的確沒有被建立,那麼這兩個線程都會建立一個執行個體(執行:instance = new Singleton1),此時就不滿足單例模式的要求。

package Singleton;public class Singleton1 {    private Singleton1(){}//private僅內建函式可以調用         private static Singleton1 instance = null;        public static Singleton1 getInstance(){        if(instance == null){            instance = new Singleton1();//建構函式聲明為private,僅內建函式可以調用,從而確保只建立一個執行個體         }        return instance;    }
}

 

2. 懶漢模式(安全執行緒)

安全執行緒:加上同步鎖(synchronized)保證安全執行緒。此時若兩個線程同時建立一個執行個體,由於在一個時刻只有一個線程能獲得同步鎖,當一個線程加上同步鎖時,另一個線程只能等待。當第一個線程發現還沒有建立執行個體時它建立一個執行個體。接著第一個線程釋放同步鎖,此時第二個線程可以加上同步鎖,但發現此時已經建立過一個執行個體,就不會重複建立一個執行個體。從而保證單例模式。

package Singleton;public class Singleton2 {    private Singleton2() {}// private僅內建函式可以調用    private static Singleton2 instance;    public static synchronized Singleton2 getInstance() {//加同步鎖,解決線程同步問題        if (instance == null) {            instance = new Singleton2();// 建構函式聲明為private,僅內建函式可以調用,從而確保只建立一個執行個體        }       return instance;    }}

 

3. 懶漢模式(雙重校正鎖)

考慮第2種方法由於加鎖是一個耗時的操作,所以我們想辦法減少加鎖的次數。

本方法:如果執行個體已經被建立,直接返回即可;如果執行個體沒有被建立,此時加鎖保證安全執行緒再建立執行個體。

注意:關鍵字volatile

Volatile的作用強制每次都直接讀記憶體,阻止重排序,確保 voltile 類型的值一旦被寫入緩衝必定會被立即更新到主存

因為:在JAVA多線程環境下,每個Java線程除了共用的虛擬機器棧外和Java堆之外,還存在一個獨立私人的堆記憶體(預設情況下大小為512KB,線上程被建立時分配,可以通過-Xss選項調節其預設值大小)。每個線程獨立運行,彼此之間都不可見,線程的私人堆記憶體中保留了一份主記憶體的拷貝,只有在特定需求的情況下才會與主存做互動(複製/重新整理)。此時就會出現一種情況,雖然在某個線程私人的堆記憶體上已經建立出一個執行個體,由於線程還沒有與主記憶體進行互動,導致主記憶體上還沒有這個執行個體。此時用volatile就可以解決這個問題。

package Singleton;public class Singleton3 {    private Singleton3() {}// private僅內建函式可以調用    private volatile static Singleton3 instance = null;    public static synchronized Singleton3 getInstance() {//加同步鎖,解決線程同步問題        if (instance == null) {//加鎖耗時,減少加鎖的次數            synchronized (Singleton3.class){                if (instance == null) {                    instance = new Singleton3();// 建構函式聲明為private,僅內建函式可以調用,從而確保只建立一個執行個體                }            }        }        return instance;    }}

4. 餓漢模式

餓漢模式: 相對於懶漢模式,餓漢模式就是在類載入的時候就建立執行個體。

這種方式基於classloder機制避免了多線程的同步問題,instance在類裝載時就執行個體化。下面就是餓漢模式的兩種寫法。

package Singleton;public class Singleton4 {    private static Singleton4 instance = new Singleton4();      private Singleton4 (){}    public static Singleton4 getInstance() {           return instance;      }  }

 

package Singleton;public class Singleton5 {     private static Singleton5 instance = null;       static {            instance = new Singleton5();       }       private Singleton5 (){}     public static Singleton5 getInstance() {           return Singleton5.instance;       }  }

 

5. 靜態內部類

這種方式同樣利用了classloder的機制來保證初始化instance時只有一個線程,它跟餓漢模式不同的是:餓漢模式只要Singleton類被裝載了,那麼instance就會被執行個體化(沒有達到lazy loading效果),而這種方式是Singleton類被裝載了,instance不一定被初始化。因為SingletonHolder類沒有被主動使用,只有顯示通過調用getInstance方法時,才會顯示裝載SingletonHolder類,從而執行個體化instance。想象一下,如果執行個體化instance很消耗資源,我想讓他消極式載入,另外一方面,我不希望在Singleton類載入時就執行個體化,因為我不能確保Singleton類還可能在其他的地方被主動使用從而被載入,那麼這個時候執行個體化instance顯然是不合適的。這個時候,這種方式相比餓漢模式就顯得很合理。

package Singleton;public class Singleton6 {    private static class SingletonHolder {        private static final Singleton6 INSTANCE = new Singleton6();    }    private Singleton6() {}    public static final Singleton6 getInstance() {        return SingletonHolder.INSTANCE;//單例模式延遲到SingletonHolder這個類載入    }}

 

6. 枚舉

枚舉:它不僅能避免多線程同步問題,而且還能防止還原序列化重新建立新的對象。

package Singleton;public enum Singleton7 {    INSTANCE;  }

 

參考資料

  1. 《Think in Java》
  2. 《Head first design pattern》
  3. 《劍指offer》
  4. http://www.blogjava.net/kenzhh/archive/2013/03/15/357824.html
  5. http://www.tuicool.com/articles/uyEvaeQ

Java 設計模式---單例模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.