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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:52:20