系统设计 --- 双重检查锁定

系统设计 --- 双重检查锁定

双重检查锁定(Double-Checked Locking,DCL) 是一种在并发情况下确认某一变量状态的方法。其核心思想是:在加锁前后各检查一次变量,避免错误操作

java 复制代码
public class MyClass {
    class myVar
    
    public static void check() {
    
    	// 第一次检查:不加锁   
        if (myVar满足条件) {  				               
            // 加锁
            synchronized (myVar.class) {
            	// 第二次检查:加锁后     
                if (myVar满足条件) {          
                    //执行操作
                }
            }
        }
    }
}

经典使用场景

  1. 延迟初始化,如单例类中
java 复制代码
//Java代码
public class Singleton {

    private static volatile Singleton instance; // 注意 volatile 关键字

    public static Singleton getInstance() {
        if (instance == null) {                  // 第一次检查:不加锁
            synchronized (Singleton.class) {     // 加锁
                if (instance == null) {          // 第二次检查:加锁后
                    instance = new Singleton();  // 初始化
                }
            }
        }
        return instance;
    }
}
  1. 状态标志更新
csharp 复制代码
//C# 代码
public class ConnectionManager
{
    private volatile ConnectionState _state = ConnectionState.Disconnected;
    private readonly object _stateLock = new object();
    
    public void Connect()
    {
        if (_state == ConnectionState.Connected) return;
        
        lock (_stateLock)
        {
            // 第二次检查(可能有其他线程已链接)
            if (_state == ConnectionState.Connected) return;
            
            // 执行连接操作
            EstablishConnection();
            StartHeartbeat();
            
            _state = ConnectionState.Connected;
        }
    }
}
  1. 线程安全的缓存实现
csharp 复制代码
public class ThreadSafeCache<TKey, TValue>
{
    private readonly Dictionary<TKey, TValue> _cache = new Dictionary<TKey, TValue>();
    private readonly object _lock = new object();
    
    public TValue GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
    {
        // 第一次检查(无锁)
        if (_cache.TryGetValue(key, out var value))
        {
            return value;
        }
        
        lock (_lock)
        {
            // 第二次检查(可能有其他线程已添加)
            if (!_cache.TryGetValue(key, out value))
            {
                value = valueFactory(key); // 可能耗时的创建过程
                _cache[key] = value;
            }
            return value;
        }
    }
}