1. 程式人生 > >Java 多執行緒(四)—— 單例模式

Java 多執行緒(四)—— 單例模式

這篇部落格介紹執行緒安全的應用——單例模式。

單例模式

  單例模式,是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中,應用該模式的類一個類只有一個例項。即一個類只有一個物件例項。

例項:

/**
 * @author: ChenHao
 * 關於懶漢式的執行緒安全問題,使用同步機制
 * 對於一般的方法內,使用同步方法塊,可以考慮使用this
 * 對於靜態方法而言,使用當前類充當鎖。
 */
public class TestSingleton {
    public static void main(String[] args) {
        System.out.println(MySingle.getInstance());
        System.out.println(MySingle.getInstance());
    }
}

class MySingle{ //宣告一個私有的靜態變數,第一次呼叫才初始化,避免記憶體浪費。 private volatile static MySingle instance=null; //讓構造器為private私有化,避免外部直接建立物件 private MySingle(){} public static MySingle getInstance(){ if(null ==instance){//提高效率:如果已經存在物件,則不進行鎖等待,直接返回物件,只有當物件為空才會進入鎖等待,這裡可以在第一個進入鎖建立物件後,sleep10秒來放大效果
//這裡有五個執行緒等待 synchronized(MySingle.class){ //第一次:當一個執行緒進來後,其他執行緒都在鎖外面 //第一個執行緒建立物件後,釋放鎖,其他執行緒得到鎖後,如果instance不為null,則不需要建立 if(null ==instance){ instance =new MySingle(); try { Thread.currentThread().sleep(
1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } return instance; } }

程式碼分析:多個執行緒同時建立MySingle類的例項,比如現在有6個執行緒,第一次同時呼叫getInstance()靜態方法,

  執行緒A獲取了鎖,其他5個執行緒都在synchronized(MySingle.class)外面等待,第一個執行緒建立物件後,釋放鎖,其他執行緒得到鎖後,如果instance不為null,則不需要建立;

  第一個if(null ==instance)作用是提高效率:如果已經存在物件,則不進行鎖等待,直接返回物件,只有當物件為空才會進入鎖等待,這裡可以在第一個進入鎖建立物件後,sleep10秒來放大效果,此時已經建立了instance ,但是還沒有釋放鎖,所以新來的執行緒不需要再等待鎖,直接使用已經建立好的instance;

  第二個if(null ==instance)判斷instance是否已經存在,如果第一個執行緒已經建立instance,並釋放鎖,接下來的執行緒進入後則不需要再建立;

執行結果:輸出相同的物件例項