餓漢模式:
class Single{
private staitc final Single s= new Single();
private Single(){}
public static Single getSingle(){
return s;
}
}
懶漢模式:
class Single{
private static Single s= null;
private Single(){}
public static Single getSingle(){
if(s == null){
-->A線程
-->B線程
s = new Single();
return s;
}
}
}
在這里使用懶漢模式有一個安全性問題:
就是s為共享數據,可能會並發的訪問getSingle()方法。當多線程訪問時,一個A線程進來后,可能調用了sleep()方法在這里沉睡;一個B線程也可能在沉睡,當A線程醒來后,就會new一個對象,B線程醒來也會new一個對象;這樣就不符合我們單例模式的特點了。
解決方案:在getSingle()方法前增加synchronized進行同步
另一個問題,當加了synchronized后,那么很多線程來訪問時,都要判斷一下鎖是哪個,這就造成速率下降,解決方案如下:
public staitc Single getSingle(){
if(s == null){
synchronized(Single.class){ -->B線程,等着A解鎖才讓進去
if(s == null){
-->A線程
s = new Single();
}
}
return s;
}
}
思路:
當s == null時,A線程進來了,他加了一下鎖后進入第二個if(s ==null){},然后沉睡;此時,B也通過了第一個if(s == null),當B玩下執行時,遇到了synchronized(),發現這里A進行了加鎖,沒辦法B線程只能等着,等A把鎖解了。此時,A線程醒來了,它new 了一個對象后,繼續玩下執行,然后把鎖解了,這是s不等於null了。B發現A解鎖了,它繼續往下執行,發現s不等於null了,那它直接返回了A創建的那個對象s。當c線程訪問getSingle方法時,只需判斷s是否為null,而不用去判斷鎖對象了。因為s不等於null了,所以直接返回對象,這樣就提高了效率
懶漢模式是延遲加載的實例,面對多線程訪問時,需要進行同步代碼塊,為了增加效率,又要使用雙重判斷
注意:非靜態的同步函數對象是this,靜態的同步函數對象是:字節碼對象。即類.class;
Java小生店鋪:
Pc端:http://shop125970977.taobao.com/index.htm
手機端:搜索 java小生店鋪
希望店鋪的資料能幫助到你!!!