Dart Lock类来自synchronized包

Dart Lock 使用总结

概述

在Dart中,static Lock _lock = Lock(); 通常用于控制异步操作的并发访问,确保某些代码块在同一时间只能被一个异步操作执行。Lock类来自synchronized包。

基本概念

什么是Lock?

  • Lock是一种同步原语,用于保护共享资源
  • 在Dart的异步环境中,用于防止多个Future同时访问临界区
  • 与传统线程锁不同,Dart的Lock是基于事件循环的

为什么使用static?

dart 复制代码
class MyService {
  static Lock _lock = Lock();  // 类级别的锁,所有实例共享
  
  // 或者
  final Lock _instanceLock = Lock();  // 实例级别的锁
}

依赖安装

yaml 复制代码
dependencies:
  synchronized: ^3.1.0

基本用法

1. 基础锁定示例

dart 复制代码
import 'package:synchronized/synchronized.dart';

class Counter {
  static Lock _lock = Lock();
  static int _count = 0;
  
  static Future<void> increment() async {
    await _lock.synchronized(() async {
      // 临界区:同时只能有一个操作执行
      final current = _count;
      await Future.delayed(Duration(milliseconds: 10)); // 模拟异步操作
      _count = current + 1;
      print('Count: $_count');
    });
  }
}

2. 文件操作保护

dart 复制代码
class FileManager {
  static Lock _fileLock = Lock();
  
  static Future<void> writeToFile(String content) async {
    await _fileLock.synchronized(() async {
      // 确保文件写入操作不会并发执行
      print('开始写入文件...');
      await Future.delayed(Duration(milliseconds: 100)); // 模拟文件写入
      print('文件写入完成: $content');
    });
  }
}

3. 数据库操作同步

dart 复制代码
class DatabaseService {
  static Lock _dbLock = Lock();
  
  static Future<void> updateUser(String userId, Map<String, dynamic> data) async {
    await _dbLock.synchronized(() async {
      // 防止同一用户的并发更新操作
      print('更新用户 $userId');
      await Future.delayed(Duration(milliseconds: 50)); // 模拟数据库操作
      print('用户 $userId 更新完成');
    });
  }
}

高级用法

1. 带返回值的锁定操作

dart 复制代码
class CacheManager {
  static Lock _cacheLock = Lock();
  static Map<String, dynamic> _cache = {};
  
  static Future<String> getOrCreate(String key) async {
    return await _cacheLock.synchronized(() async {
      if (_cache.containsKey(key)) {
        return _cache[key];
      }
      
      // 模拟创建数据的异步操作
      await Future.delayed(Duration(milliseconds: 100));
      final value = 'generated_${DateTime.now().millisecondsSinceEpoch}';
      _cache[key] = value;
      return value;
    });
  }
}

2. 超时锁定

dart 复制代码
class TimeoutLockExample {
  static Lock _lock = Lock();
  
  static Future<String> processWithTimeout() async {
    try {
      return await _lock.synchronized(() async {
        // 长时间运行的操作
        await Future.delayed(Duration(seconds: 2));
        return '处理完成';
      }).timeout(Duration(seconds: 1));
    } on TimeoutException {
      return '操作超时';
    }
  }
}

3. 多个锁的协调使用

dart 复制代码
class MultiLockExample {
  static Lock _lockA = Lock();
  static Lock _lockB = Lock();
  
  static Future<void> operationRequiringBothLocks() async {
    await _lockA.synchronized(() async {
      await _lockB.synchronized(() async {
        // 需要两个锁保护的操作
        print('执行需要双重保护的操作');
        await Future.delayed(Duration(milliseconds: 50));
      });
    });
  }
}

实际应用场景

1. 单例模式实现

dart 复制代码
class Singleton {
  static Lock _lock = Lock();
  static Singleton? _instance;
  
  Singleton._internal();
  
  static Future<Singleton> getInstance() async {
    return await _lock.synchronized(() async {
      if (_instance == null) {
        // 模拟复杂的初始化过程
        await Future.delayed(Duration(milliseconds: 100));
        _instance = Singleton._internal();
      }
      return _instance!;
    });
  }
}

2. 资源池管理

dart 复制代码
class ConnectionPool {
  static Lock _poolLock = Lock();
  static List<Connection> _availableConnections = [];
  static List<Connection> _usedConnections = [];
  
  static Future<Connection> getConnection() async {
    return await _poolLock.synchronized(() async {
      if (_availableConnections.isEmpty) {
        // 创建新连接
        await Future.delayed(Duration(milliseconds: 50));
        final newConnection = Connection();
        _availableConnections.add(newConnection);
      }
      
      final connection = _availableConnections.removeAt(0);
      _usedConnections.add(connection);
      return connection;
    });
  }
  
  static Future<void> releaseConnection(Connection connection) async {
    await _poolLock.synchronized(() async {
      _usedConnections.remove(connection);
      _availableConnections.add(connection);
    });
  }
}

class Connection {
  // 连接实现
}

3. API限流控制

dart 复制代码
class RateLimiter {
  static Lock _lock = Lock();
  static List<DateTime> _requests = [];
  static const int maxRequests = 10;
  static const Duration timeWindow = Duration(minutes: 1);
  
  static Future<bool> canMakeRequest() async {
    return await _lock.synchronized(() async {
      final now = DateTime.now();
      
      // 清理过期的请求记录
      _requests.removeWhere(
        (requestTime) => now.difference(requestTime) > timeWindow,
      );
      
      if (_requests.length >= maxRequests) {
        return false; // 达到限流阈值
      }
      
      _requests.add(now);
      return true;
    });
  }
}

性能考虑

1. 锁的粒度

dart 复制代码
// ❌ 锁粒度过大
class BadExample {
  static Lock _lock = Lock();
  
  static Future<void> processMultipleItems(List<String> items) async {
    await _lock.synchronized(() async {
      for (final item in items) {
        await processItem(item); // 整个循环都被锁定
      }
    });
  }
}

// ✅ 适当的锁粒度
class GoodExample {
  static Lock _lock = Lock();
  
  static Future<void> processMultipleItems(List<String> items) async {
    for (final item in items) {
      await _lock.synchronized(() async {
        await processItem(item); // 只锁定必要的部分
      });
    }
  }
}

2. 避免死锁

dart 复制代码
// ❌ 可能导致死锁
class DeadlockRisk {
  static Lock _lockA = Lock();
  static Lock _lockB = Lock();
  
  static Future<void> method1() async {
    await _lockA.synchronized(() async {
      await _lockB.synchronized(() async {
        // 操作
      });
    });
  }
  
  static Future<void> method2() async {
    await _lockB.synchronized(() async {
      await _lockA.synchronized(() async {
        // 操作 - 可能死锁
      });
    });
  }
}

// ✅ 避免死锁的方法
class DeadlockFree {
  static Lock _masterLock = Lock();
  
  static Future<void> method1() async {
    await _masterLock.synchronized(() async {
      // 所有需要多重锁定的操作都使用同一个锁
    });
  }
  
  static Future<void> method2() async {
    await _masterLock.synchronized(() async {
      // 操作
    });
  }
}

错误处理

dart 复制代码
class ErrorHandlingExample {
  static Lock _lock = Lock();
  
  static Future<String> safeOperation() async {
    try {
      return await _lock.synchronized(() async {
        // 可能抛出异常的操作
        if (DateTime.now().millisecond % 2 == 0) {
          throw Exception('模拟错误');
        }
        return '操作成功';
      });
    } catch (e) {
      print('锁定操作中发生错误: $e');
      return '操作失败';
    }
  }
}

测试和调试

dart 复制代码
class DebugLockExample {
  static Lock _lock = Lock();
  static int _operationCount = 0;
  
  static Future<void> debugOperation(String operationId) async {
    print('[$operationId] 等待获取锁...');
    
    await _lock.synchronized(() async {
      print('[$operationId] 获得锁,开始执行');
      _operationCount++;
      
      await Future.delayed(Duration(milliseconds: 100));
      
      print('[$operationId] 操作完成,操作计数: $_operationCount');
    });
    
    print('[$operationId] 释放锁');
  }
}

最佳实践

  1. 合理选择锁的作用域 :使用static还是实例变量
  2. 最小化锁定时间:只保护必要的代码段
  3. 避免在锁内执行长时间操作:特别是I/O操作
  4. 一致的锁定顺序:避免死锁
  5. 适当的错误处理:确保异常不会导致锁泄漏
  6. 性能测试:在高并发场景下测试锁的性能影响

注意事项

  • Dart的Lock是基于事件循环的,不是真正的线程锁
  • 在Isolate间不能共享Lock实例
  • 过度使用锁可能影响异步操作的性能
  • 始终考虑是否真的需要锁,有时使用其他并发控制方式更合适

总结

static Lock _lock = Lock(); 是Dart中实现异步操作同步控制的重要工具,正确使用可以避免竞态条件,确保数据一致性。关键是理解其异步特性,合理控制锁的粒度,并遵循最佳实践。

相关推荐
天渺工作室2 天前
Flutter 版的 NVM——FVM 使用指南
flutter·dart
Nathan202406163 天前
Flutter - InheritedWidget
flutter·dart
空中海4 天前
2.3 组件复用与组合
flutter·dart
空中海7 天前
3.3 第三方框架
flutter·dart
空中海8 天前
2.7 列表与滚动性能优化
flutter·性能优化·dart
空中海8 天前
2.4 绘制与动画
flutter·dart
空中海8 天前
2.6 表单与输入处理
flutter·dart
空中海9 天前
1.1 Flutter 简介与架构原理
flutter·dart
空中海9 天前
1.3 Dart 核心语言特性
flutter·dart
空中海9 天前
2.5 手势识别与交互系统
flutter·交互·dart