static在不保证初始化是线程安全的.NET早期版本中,单例的此线程安全版本是必需的。在更现代的框架版本中,通常首选静态初始化的单例,因为按照以下模式很容易犯下实现错误。
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)检查完成了两次:一次在获取锁之前,一次在之后。即使没有第一个null检查,此实现仍将是线程安全的。但是,这意味着每次请求实例时都将获取一个锁,这将导致性能下降。添加第一个空检查,以便除非有必要,否则不获取锁定。第二次空检查确保只有第一个获取锁的线程才能创建实例。其他线程将找到要填充的实例,并向前跳过。