懶惰的執行緒安全 Singleton(使用雙重鎖定)
在 .NET 的早期版本中,這種執行緒安全版本的單例是必需的,其中 static
初始化不保證是執行緒安全的。在框架的更現代版本中,通常首選靜態初始化單例, 因為在以下模式中很容易出現實現錯誤。
public sealed class ThreadSafeSingleton
{
private static volatile ThreadSafeSingleton instance;
private static object lockObject = new Object();
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance
{
get
{
if (instance == null)
{
lock (lockObject)
{
if (instance == null)
{
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
}
}
請注意,if (instance == null)
檢查完成兩次:一次獲取鎖定之前,一次之後。即使沒有第一次空檢查,此實現仍然是執行緒安全的。但是,這意味著每次請求例項時都會獲取鎖,這會導致效能受損。新增第一個空檢查,以便除非必要,否則不會獲取鎖定。第二次空檢查確保只有第一個獲取鎖的執行緒才會建立例項。其他執行緒將找到要填充的例項並向前跳過。