Swift中以全局并发队列为目标的自定义串行队列为何无法并发执行?
DispatchQueue目标队列机制的核心逻辑解析
问题背景
你对DispatchQueue的目标队列机制存在两个疑惑场景:
场景1:标记为并发的队列,以主队列(串行)为目标时执行串行
你创建了带.concurrent属性的队列,但指定主队列作为目标后,任务串行执行:
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent, target: DispatchQueue.main) concurrentQueue.async { for i in 1...5 { print(i) } } concurrentQueue.async { for i in 6...10 { print(i) } }
输出结果:
1 2 3 4 5 6 7 8 9 10
原因解析
目标队列(主队列)的作用是接收原队列调度后的任务并执行,而非直接替换原队列的特性:
- 两个异步任务会先进入
concurrentQueue的并发队列等待 - 但主队列是串行队列,它会逐个取出
concurrentQueue中的任务,放到自身的串行执行流中运行 - 最终任务只能依次执行,呈现串行输出的结果
场景2:串行队列以全局并发队列(并发)为目标时仍执行串行
你创建了串行队列,指定全局并发队列作为目标后,任务依旧串行执行:
let serialQueue = DispatchQueue(label: "serialQueue", target: DispatchQueue.global(qos: .background)) serialQueue.async { for i in 1...5 { print(i) } } serialQueue.async { for i in 6...10 { print(i) } }
输出结果:
1 2 3 4 5 6 7 8 9 10
原因解析
队列的串行/并发属性是自身固有特性,由创建时的attributes(默认不带属性即为串行)决定,目标队列无法修改这一点:
- 两个异步任务进入
serialQueue的串行队列后,必须先执行完第一个任务,才会将第二个任务提交给目标队列的线程池 - 目标队列仅提供执行任务的线程资源,不改变原队列的任务调度顺序,因此最终还是串行输出
核心总结
- 队列的串行/并发特性是自身固有属性,目标队列无法覆盖
- 目标队列的核心作用:
- 提供任务执行的线程资源(比如全局并发队列的线程池)
- 继承调度优先级(QoS)
- 实现多队列的层级调度管理(将多个自定义队列的任务汇总到一个目标队列统一调度)
内容的提问来源于stack exchange,提问作者Stephanovits
相关产品推荐
相关产品推荐

