You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用全局Actor保障串行执行,读写操作却并行运行?

问题原因分析

你的代码里读写操作并行执行的核心原因是:Task.sleep会挂起当前Actor任务并释放Actor的执行权,导致其他等待的Actor任务被提前调度。

详细执行流程

  1. 测试中task1提交write任务到DataStorageActor的队列,Actor开始执行write方法,打印Write started。
  2. 当write方法执行到try await Task.sleep(5_000_000_000)时,这个await会让当前Actor任务挂起——因为Task.sleep是在全局执行上下文运行的异步操作,不依赖当前Actor。此时Actor会释放执行权,去处理队列里的下一个等待任务(也就是task2提交的read操作)。
  3. read方法在Actor上执行完成,读取到还未被赋值的nil,打印相关日志后返回。
  4. 5秒后Task.sleep完成,Actor回到挂起的write任务,执行storage[key] = value并打印Write completed。
  5. 此时task1才完成,测试继续等待task2,最终断言失败。

为什么全局Actor没起到预期的串行效果?

全局Actor保证的是Actor任务队列的串行执行,但它的串行性是针对「Actor任务的执行片段」,而非整个异步方法的全程。当方法内部await一个脱离Actor上下文的异步操作时,Actor会暂时让出执行权,优先处理队列中的其他任务。


修复方案

如果你需要让整个写入操作(包括模拟的耗时过程)都独占Actor,不让其他操作插队,可以采用以下方式:

用同步耗时操作替代Task.sleep

将Task.sleep换成同步的阻塞延迟(仅用于测试场景,生产环境不推荐阻塞Actor线程):

func write(key: String, value: String) async throws {
    print("\(Date()): Write started")
    // 同步阻塞5秒,不会释放Actor执行权
    Thread.sleep(forTimeInterval: 5)
    storage[key] = value
    print("\(Date()): Write completed for key: \(key)")
}

修改后,write方法会全程占用Actor执行权,read操作必须等write完全执行完毕才能开始,符合你预期的串行效果。

内容的提问来源于stack exchange,提问作者user2828120

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:28:12