1. 程式人生 > >執行緒涉及單例模式

執行緒涉及單例模式

/**
 * 單例模式涉及的兩個問題
 * 
 * @author 羅摩銜那
 *
 */
/*
 * 惡漢式
 * 優點:當類被載入的時候,已經建立好了一個靜態的物件,因此,是執行緒安全的
 * 缺點:這個物件還沒有被使用就被創建出來了
 */
class Single
{
    private static final Single s=new Single();//
    private Single() {}//私有無參構造方法
    public static Single getInstance()
    {
        return s;
    }
}
/*
 * 懶漢式
 * 優點:按需載入物件,只有物件被使用的時候才會被建立
缺點:這種寫法不是執行緒安全的,例如當第一個執行緒執行判斷語句if(s = null)時, 
第二個執行緒執行判斷語句if(s = null),接著第一個執行緒執行語句test = new Test(), 
第二個執行緒也執行語句test = new Test(),在這種多執行緒環境下,可能會創建出來兩個物件
 
*/ class Singler { private static Singler s=null; private Singler() {}; public static /*synchronized*/ Singler getInstance() { /* * 一.-->執行緒0 -->執行緒1 當執行緒0進入建立物件 * 執行緒1進入不用判斷也建立物件--出問題 * 二.當給函式加上同步性質synchronized後,執行緒進入,不為空 * 也就不判斷,那麼就不用建立物件,問題解決 * 三.下面加同步鎖是為了執行緒安全問題 * 最外面再加一次判斷是為了效率問題
*/ if(s==null) { synchronized(Singler.class) { if(s==null) s=new Singler(); } } return s; } } public class SingleDemo { public static void main(String[] args) { System.out.println("Hello World!"); } }

第三種情況時:進入執行緒0,判斷是否為null,獲得執行緒鎖佔位,再判斷是null建立物件,返回一個s.

假設執行緒0釋放執行權,執行緒1判斷完後,是進不來的--因為0執行緒的執行資格還沒釋放,接著釋放執資格.

接著執行緒1進入,判斷為null,獲得執行緒鎖佔位,再次判斷s不為空.