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中实现异步操作同步控制的重要工具,正确使用可以避免竞态条件,确保数据一致性。关键是理解其异步特性,合理控制锁的粒度,并遵循最佳实践。

相关推荐
农夫三拳_有点甜7 小时前
Dart 并发编程详细总结1
dart
农夫三拳_有点甜12 小时前
Dart 运算符和操作符详细总结
dart
农夫三拳_有点甜12 小时前
Dart Timer 全面总结指南
dart
农夫三拳_有点甜12 小时前
Dart Class API 详细总结
dart
cowice4 天前
Dart基础知识
flutter·dart
AhhhhDong11 天前
记录工作中遇到的几个Dart语言的坑和bug
dart
叽哥16 天前
Flutter面试:Dart基础2
flutter·面试·dart
fouryears_2341720 天前
Flutter InheritedWidget 详解:从生命周期到数据流动的完整解析
开发语言·flutter·客户端·dart
华科云商xiao徐25 天前
异步并发×编译性能:Dart爬虫的实战突围
爬虫·数据可视化·dart