有一个用于读写字典数据的数据存储。我使用了一个全局 Actor,它可以保证操作的串行执行。
代码示例:
@globalActor
struct DataStorageActor {
actor ActorType { }
static let shared: ActorType = ActorType()
}
@DataStorageActor
class CustomDataStorage {
private var storage: [String: String] = [:]
func write(key: String, value: String) async throws {
print("\(Date()): Write started")
try await Task.sleep(nanoseconds: 5_000_000_000)
storage[key] = value
print("\(Date()): Write completed for key: \(key)")
}
func read(key: String) async throws -> String? {
print("\(Date()): Read started")
let value = storage[key]
print("\(Date()): Read completed for key: \(key)")
return value
}
}
并编写了一个单元测试:
@Test(arguments: ["Very long string"])
func testSerialExecution(input: String) async throws {
let storage = CustomDataStorage()
let task1 = Task {
try await storage.write(key: "test", value: input)
}
let task2 = Task {
try await Task.sleep(nanoseconds: 2_000_000_000)
let value = try await storage.read(key: "test")
print("\(Date()): Received value: \(value ?? "nil")")
return value
}
print("wait task 1")
_ = try await task1.value
print("wait task 2")
let value: String? = try await task2.value
print("check result")
#expect(value == input)
}
- 在一个单独的线程中,我启动一个长写入操作(5秒)
- 在单独的线程中,我启动了延迟 2 秒的读取操作
- 我希望读取操作等待写入操作完成
但读取操作是并行运行的,记录如下:
wait task 1
2025-04-07 12:43:03 +0000: Write started
2025-04-07 12:43:05 +0000: Read started
2025-04-07 12:43:05 +0000: Read completed for key: test
2025-04-07 12:43:05 +0000: Received value: nil
2025-04-07 12:43:08 +0000: Write completed for key: test
wait task 2
check result
为什么它会这样工作?