Double-checked Locking,嚴格意義上來講不屬於無鎖範疇,無論什麼時候當臨界區中的代碼僅僅需要加鎖一次,同時當其獲取鎖的時候必須是線程安全的,此時就可以利用 Double-checked Locking 模式來減少鎖競爭和加鎖載荷。目前Double-checkedLocking已經廣泛應用於單例 (Singleton)模式中。
Double-checked Locking有以下特點:
Double-checked Locking模式是Singleton的多線程版本。
Double-checked Locking模式依舊會使用鎖——臨界區鎖定,不要以爲可以避免使用鎖。
Double-checked Locking解決的問題是:當多個線程存在訪問臨界區企圖時,保證了臨界區只需要訪問一次。
以Singleton爲例,爲了防止多次分配,通常Singleton的實現方式是:
// 實現1
Class singleton
{
singleton* get_instance()
{
lock();
if (instance == 0)
{
instance = new singleton;
}
unlock();
return instance;
}
}
這裏存在的問題是:無論是否已經初始化都要加鎖,增加了負荷,已經沒有所謂的併發性能了。
要增加併發性能,可以先判斷是否已經分配,在沒分配的情況下才加鎖,也許你想要改成下面這個樣子:
// 實現2
Class singleton
{
singleton* get_instance()
{
if (instance == 0)
{
lock();
instance = new singleton;
unlock();
}
return instance;
}
}
這裏存在的問題是:不能保證臨界區只初始化一次,沒能實現singleton的基本功能。
// 實現3 - Double-checkedLocking
Class singleton
{
singleton* get_instance()
{
if (instance == 0)
{
lock();
if (instance == 0 )
{
instance = new singleton;
}
unlock();
}
return instance;
}
}
嚴格的說,Double-checked locking不屬於無鎖編程的範疇,但由原來的每次加鎖訪問到大多數情況下無須加鎖,就是一個巨大的進步。