public class SingLeton
{
private static SinglLeton singleton=null;
private SingLeton()
{
}
public static SingLeton getsingleton()
{
if(singleton==null)
{
SingLeton singleton=new SingLeton();
}
return singleton;
}
}
上面的代碼就是一個單例模式的類,在使用單例模式時需要注意以下幾點:
1.單例模式(Singleton)的構造函數必須是私有的(private),以保證程序中不能使用new()來實例,達到整個程序中只有唯一一個實例的目的;
2.必須提供一個靜態的全局函數訪問點,以確保外部能訪問該實例;
上面的單例模式(Singleton)中,在只有單線程去執行時是正確的,但如果在使用多線程時就會出現有多個實例,顯然違背了單例模式(Singleton)的條件;哪么在多線程中我們應該怎樣去實現單例模式(Singleton)呢???
下面我們就來看看多線程中單例模式(Singleton)的實現:
在多線程中不能使用上面代碼中的單例模式(Singleton)的原因是因為它違反了整個程序中只有唯一一個實例的條件,所以我們要想在多線程中使用單例模式(Singleton)就必須實現只有唯一一個實例這一條件;在多線程中因為每條線程都是獨立訪問的,所以才會出多個實例;哪么只要我們在if條件前加上鎖(lock)就能避免出現多個實例;下面我們來看看代碼的實現:
public class SingLeton
{
private static SinglLeton singleton=null;
private static readonly object lockS=new object();//確保線程同步
private SingLeton()
{
}
public static SingLeton getsingleton()
{
lock(lockS)
{
if(singleton==null)
{
SingLeton singleton=new SingLeton();
}
}
return singleton;
}
}
以上的代碼就是單例模式(Singleton)在多線程中的實現;
在上面的多線程中的單例模式中是否是最好的呢?是不是使用最少資源呢?還能不能優化類呢?
下面我們就先來分析多線程中單例模式(Singleton)的運行:
當程序的線程跑到鎖(lock)的時候就會停下來判斷是否有線程在用鎖(lock)里面的代碼,沒有就才會進入,哪么如果多條線程跑到鎖(lock)的時候就只能一條一條進入鎖(lock)(當然這本來就是多線程鎖(lock)的功能);進入鎖里面判斷到已有實例就跳出if不進行實例化。
上面我們對多線程中的單例模式(Singleton)做了分析;在上面的分析中我們可以看出,每條線程都要先進入鎖(lock)才做了判斷;但在沒進入鎖之前線程就知道已經可以判斷出是否有過實例,哪為什么我們不在外面進行判斷一次后在進入鎖(lock)呢?好!既然這樣我們把代碼改改看看效果,我們在鎖(lock)的外面加多一次判斷
public class SingLeton
{
private static SinglLeton singleton=null;
private static raedonly object lockS=new object();//確保線程同步
private SingLeton()
{
}
public static SingLeton getsingleton()
{
if(singleton==null)
lock(lockS)
{
if(singleton==null)
{
SingLeton singleton=new SingLeton();
}
}
}
return singleton;
}
}
從更改后的代碼上看來,有人會問為什么要用兩次if呢?有必要嗎?外面不都判斷過了嗎?可以去掉一個if條件判斷啊,這樣代碼不是更加少嗎?
下面我就來解釋下為什么要用到兩次if。
其實用兩個if的原因還是在於多線程的特性,還是因為多線程訪問函數時都是獨立訪問的,所以才要用到兩個if(說到這里大家都應該明白了,所以就不說下去了(不明白的可以在去了解多線程的物性))。
這是第一次寫博客、文采也不好,有什么不對的寫的不好的請大家見涼。。。。。。