系统设计 --- 双重检查锁定
双重检查锁定(Double-Checked Locking,DCL) 是一种在并发情况下确认某一变量状态的方法。其核心思想是:在加锁前后各检查一次变量,避免错误操作
java
public class MyClass {
class myVar
public static void check() {
// 第一次检查:不加锁
if (myVar满足条件) {
// 加锁
synchronized (myVar.class) {
// 第二次检查:加锁后
if (myVar满足条件) {
//执行操作
}
}
}
}
}
经典使用场景
- 延迟初始化,如单例类中
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;
}
}
- 状态标志更新
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;
}
}
}
- 线程安全的缓存实现
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;
}
}
}