向同一DispatchQueue提交任务:为何sleep更久的Task1先完成?
问题解答
为什么你的代码里Task1先完成?
你创建的DispatchQueue没有指定额外属性,默认是串行队列。串行队列的工作逻辑很简单:必须等前一个任务彻底执行完毕,才会从队列里取出下一个任务启动执行。
你的代码里Task1先被提交到队列,所以它会先启动——哪怕它要sleep3秒,Task2也得等Task1执行完(包括sleep和打印操作),才会开始自己的sleep和打印。所以最终你会看到Task1 done先输出,之后才是Task2 done。
同一DispatchQueue提交任务的执行顺序规则
分两种队列类型来看:
- 串行队列:严格按照任务提交的先后顺序执行,前一个任务执行完毕后,下一个任务才会启动。任务的执行完成顺序和提交顺序完全一致,和任务自身耗时无关。
- 并发队列:如果创建队列时指定了
.concurrent属性,队列会同时调度多个任务在不同线程执行。此时任务的启动顺序还是和提交顺序一致,但执行完成的顺序取决于每个任务自身的耗时——耗时短的任务可能先完成。
举个并发队列的修改示例:
let queue = DispatchQueue(label: "name", attributes: .concurrent) queue.async { Thread.sleep(forTimeInterval: 3) print("Task1 done") } queue.async { Thread.sleep(forTimeInterval: 1) print("Task2 done") }
这时Task2会先完成输出,因为两个任务同时启动,它的sleep时间更短。
内容的提问来源于stack exchange,提问作者Smitha
相关产品推荐
相关产品推荐

