信号量
你可以用以下方法解决这个问题DispatchSemaphore
.
我们来看看这段代码。
在这里我们有一个semaphore
, storage
类型的属性String?
和一个串行队列
let semaphore = DispatchSemaphore(value: 0)
var storage: String? = nil
let serialQueue = DispatchQueue(label: "Serial queue")
Producer
func producer() {
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
storage = "Hello world!"
semaphore.signal()
}
}
这里我们有一个函数:
- 等待3秒
- 将“Hello world”写入存储
- 通过信号量发送信号
Consumer
func consumer() {
serialQueue.async {
semaphore.wait()
print(storage)
}
}
这里我们有一个函数
- 等待来自信号量的信号
- 打印存储内容
Test
现在我要运行consumer
BEFORE the producer
功能
consumer()
producer()
Result
Optional("Hello world!")
它是如何工作的?
func consumer() {
serialQueue.async {
semaphore.wait()
print(storage)
}
}
的身体consumer()
函数异步执行到串行队列中。
serialQueue.async {
...
}
这相当于你的synchronized(a)
。事实上,根据定义,串行队列将同时运行一个闭包。
闭包内的第一行是
semaphore.wait()
因此闭包的执行被停止,等待信号量发出绿灯。
这是在不同的队列(不是主队列)上发生的,因此我们不会阻塞主线程。
func producer() {
DispatchQueue.global().asyncAfter(deadline: .now() + 3) {
storage = "Hello world!"
semaphore.signal()
}
}
现在 Producer() 被执行。它在与主队列不同的队列上等待 3 秒,然后填充storage
并通过信号量发送信号。
Finally consumer()
接收到信号并可以运行最后一行
print(storage)
操场
如果您想在 Playground 中运行此代码,请记住
import PlaygroundSupport
并运行这条线
PlaygroundPage.current.needsIndefiniteExecution = true