文章目录

  • 1.串行并行,同步异步
    • 1.1 串行队列 + 同步执行
      • 主队列:死锁
      • 自定义串行队列:顺序执行,和正常执行代码一样
    • 1.2 并行队列 + 同步执行:不开启线程,按代码顺序执行
    • 1.3 串行队列 + 异步执行:一般只会新开一个线程
      • 自定义串行队列:开启新线程,几个新线程中的任务和主线程中的任务并发执行
      • 主队列:不开启新线程,会被放到最后面
    • 1.4 并发队列(自定义) + 异步执行
      • 动画
      • 代码1: for循环在queue.async里
      • 代码2:queue.async在for循环里
    • 1.5 串行和同步的区别:串行是按任务添加的先后顺序执行,同步是按代码书写(执行)的顺序执行
    • 1.6 其他实例测试
      • 实例一
      • 实例二
      • 实例三
  • 参考博客:
  • 疑问:

1.串行并行,同步异步

  • 并行队列同步执行,串行队列同步和异步执行,执行顺序是确定的

1.1 串行队列 + 同步执行

主队列:死锁


自定义串行队列:顺序执行,和正常执行代码一样

    override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")syncSerial()sleep(3)print("end:\(Thread.current)")}//串行队列 + 同步执行func syncSerial() {let serialQueue = DispatchQueue(label: "serial")for i in 0...10 {serialQueue.sync {print("\(i):\(Thread.current)")}}}

打印结果:
start:<NSThread: 0x600003f906c0>{number = 1, name = main}
0:<NSThread: 0x600003f906c0>{number = 1, name = main}
1:<NSThread: 0x600003f906c0>{number = 1, name = main}
2:<NSThread: 0x600003f906c0>{number = 1, name = main}
3:<NSThread: 0x600003f906c0>{number = 1, name = main}
4:<NSThread: 0x600003f906c0>{number = 1, name = main}
5:<NSThread: 0x600003f906c0>{number = 1, name = main}
6:<NSThread: 0x600003f906c0>{number = 1, name = main}
7:<NSThread: 0x600003f906c0>{number = 1, name = main}
8:<NSThread: 0x600003f906c0>{number = 1, name = main}
9:<NSThread: 0x600003f906c0>{number = 1, name = main}
10:<NSThread: 0x600003f906c0>{number = 1, name = main}
end:<NSThread: 0x600003f906c0>{number = 1, name = main}

1.2 并行队列 + 同步执行:不开启线程,按代码顺序执行

1.3 串行队列 + 异步执行:一般只会新开一个线程

自定义串行队列:开启新线程,几个新线程中的任务和主线程中的任务并发执行

  • end什么时候打印不确定
    override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncSerial()print("end:\(Thread.current)")}//串行队列 + 异步执行func asyncSerial(){let serialQueue = DispatchQueue(label: "serial")for i in 0...10 {serialQueue.async {print("\(i):\(Thread.current)")}}}

打印结果:
start:<NSThread: 0x6000033cc900>{number = 1, name = main}
0:<NSThread: 0x60000338c340>{number = 3, name = (null)}
end:<NSThread: 0x6000033cc900>{number = 1, name = main}
1:<NSThread: 0x60000338c340>{number = 3, name = (null)}
2:<NSThread: 0x60000338c340>{number = 3, name = (null)}
3:<NSThread: 0x60000338c340>{number = 3, name = (null)}
4:<NSThread: 0x60000338c340>{number = 3, name = (null)}
5:<NSThread: 0x60000338c340>{number = 3, name = (null)}
6:<NSThread: 0x60000338c340>{number = 3, name = (null)}
7:<NSThread: 0x60000338c340>{number = 3, name = (null)}
8:<NSThread: 0x60000338c340>{number = 3, name = (null)}
9:<NSThread: 0x60000338c340>{number = 3, name = (null)}
10:<NSThread: 0x60000338c340>{number = 3, name = (null)}


主队列:不开启新线程,会被放到最后面

  • 执行顺序始终是:start -> end -> 然后按顺序执行for循环里的任务
    override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncSerial()sleep(3)print("end:\(Thread.current)")}//串行队列 + 异步执行func asyncSerial(){let serialQueue = DispatchQueue.mainfor i in 0...10 {serialQueue.async {print("\(i):\(Thread.current)")}}}

1.4 并发队列(自定义) + 异步执行

动画

  • 并行队列异步执行:执行顺序不确定

代码1: for循环在queue.async里

  • print(“end:(Thread.current)”)什么时候执行是不确定的
  • 并发队列中只添加了一任务,这个任务是按顺序执行的,始终会按顺序打印出i
    override func viewDidLoad() {super.viewDidLoad()print("start:\(Thread.current)")asyncConcurrent()sleep(1)print("end:\(Thread.current)")}//并发队列 + 异步执行func asyncConcurrent(){let queue = DispatchQueue(label: "concurrence", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)queue.async {for i in 0...10 {print("\(i):\(Thread.current)")}}}

打印结果:
start:<NSThread: 0x6000018d4440>{number = 1, name = main}
0:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
1:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
2:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
3:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
4:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
5:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
6:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
7:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
8:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
9:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
10:<NSThread: 0x60000188cbc0>{number = 6, name = (null)}
end:<NSThread: 0x6000018d4440>{number = 1, name = main}

注释掉sleep(1)后的打印结果
start:<NSThread: 0x60000253c800>{number = 1, name = main}
end:<NSThread: 0x60000253c800>{number = 1, name = main}
0:<NSThread: 0x600002560140>{number = 5, name = (null)}
1:<NSThread: 0x600002560140>{number = 5, name = (null)}
2:<NSThread: 0x600002560140>{number = 5, name = (null)}
3:<NSThread: 0x600002560140>{number = 5, name = (null)}
4:<NSThread: 0x600002560140>{number = 5, name = (null)}
5:<NSThread: 0x600002560140>{number = 5, name = (null)}
6:<NSThread: 0x600002560140>{number = 5, name = (null)}
7:<NSThread: 0x600002560140>{number = 5, name = (null)}
8:<NSThread: 0x600002560140>{number = 5, name = (null)}
9:<NSThread: 0x600002560140>{number = 5, name = (null)}
10:<NSThread: 0x600002560140>{number = 5, name = (null)}

代码2:queue.async在for循环里

  • print(“end:(Thread.current)”)什么时候执行是不确定的
  • 并发队列中的多个任务执行顺序不确定
    //并发队列 + 异步执行func asyncConcurrent(){let queue = DispatchQueue(label: "concurrence", qos: .userInteractive, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)print("start:\(Thread.current)")for i in 0...100 {queue.async {print("\(i):\(Thread.current)")}}print("end:\(Thread.current)")}

打印结果:
start:<NSThread: 0x600003ac48c0>{number = 1, name = main}
0:<NSThread: 0x600003a86600>{number = 4, name = (null)}
1:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
4:<NSThread: 0x600003a86600>{number = 4, name = (null)}
2:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
6:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
5:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
3:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
7:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
8:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
9:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
10:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
11:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
12:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
13:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
14:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
15:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
16:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
17:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
18:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
19:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
20:<NSThread: 0x600003a86600>{number = 4, name = (null)}
21:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
22:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
24:<NSThread: 0x600003aa6380>{number = 9, name = (null)}
23:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
25:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
26:<NSThread: 0x600003ab1ec0>{number = 10, name = (null)}
27:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
89:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
91:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
30:<NSThread: 0x600003abd100>{number = 14, name = (null)}
92:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
32:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
33:<NSThread: 0x600003ab24c0>{number = 17, name = (null)}
95:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
96:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
35:<NSThread: 0x600003ab30c0>{number = 19, name = (null)}
97:<NSThread: 0x600003ab24c0>{number = 17, name = (null)}
38:<NSThread: 0x600003aa7540>{number = 22, name = (null)}
39:<NSThread: 0x600003abd2c0>{number = 23, name = (null)}
40:<NSThread: 0x600003a81040>{number = 24, name = (null)}
41:<NSThread: 0x600003ab1440>{number = 25, name = (null)}
42:<NSThread: 0x600003aa6580>{number = 26, name = (null)}
43:<NSThread: 0x600003a89040>{number = 27, name = (null)}
44:<NSThread: 0x600003ab15c0>{number = 28, name = (null)}
45:<NSThread: 0x600003abd580>{number = 29, name = (null)}
end:<NSThread: 0x600003ac48c0>{number = 1, name = main}
46:<NSThread: 0x600003aa7740>{number = 30, name = (null)}
47:<NSThread: 0x600003a8b700>{number = 31, name = (null)}
48:<NSThread: 0x600003abd640>{number = 32, name = (null)}
49:<NSThread: 0x600003aa7800>{number = 33, name = (null)}
50:<NSThread: 0x600003a8ad00>{number = 34, name = (null)}
51:<NSThread: 0x600003abd700>{number = 35, name = (null)}
52:<NSThread: 0x600003aa7a40>{number = 36, name = (null)}
53:<NSThread: 0x600003ab3bc0>{number = 37, name = (null)}
54:<NSThread: 0x600003abd7c0>{number = 38, name = (null)}
55:<NSThread: 0x600003aa7980>{number = 39, name = (null)}
56:<NSThread: 0x600003ab3d40>{number = 40, name = (null)}
57:<NSThread: 0x600003abd880>{number = 41, name = (null)}
58:<NSThread: 0x600003aa7880>{number = 42, name = (null)}
59:<NSThread: 0x600003ab3e40>{number = 43, name = (null)}
60:<NSThread: 0x600003a8a040>{number = 44, name = (null)}
61:<NSThread: 0x600003aaffc0>{number = 45, name = (null)}
62:<NSThread: 0x600003ab3e80>{number = 46, name = (null)}
63:<NSThread: 0x600003abd940>{number = 47, name = (null)}
64:<NSThread: 0x600003ab3f40>{number = 48, name = (null)}
65:<NSThread: 0x600003aaff00>{number = 49, name = (null)}
66:<NSThread: 0x600003abda40>{number = 50, name = (null)}
67:<NSThread: 0x600003ab1180>{number = 51, name = (null)}
68:<NSThread: 0x600003a8a100>{number = 52, name = (null)}
69:<NSThread: 0x600003aafe40>{number = 53, name = (null)}
70:<NSThread: 0x600003abdb00>{number = 54, name = (null)}
71:<NSThread: 0x600003a895c0>{number = 55, name = (null)}
72:<NSThread: 0x600003ab2080>{number = 56, name = (null)}
73:<NSThread: 0x600003abdbc0>{number = 57, name = (null)}
74:<NSThread: 0x600003aafd40>{number = 58, name = (null)}
75:<NSThread: 0x600003a89a40>{number = 59, name = (null)}
76:<NSThread: 0x600003abdc80>{number = 60, name = (null)}
77:<NSThread: 0x600003aafc40>{number = 61, name = (null)}
78:<NSThread: 0x600003a89180>{number = 62, name = (null)}
79:<NSThread: 0x600003aafb80>{number = 63, name = (null)}
80:<NSThread: 0x600003abdd40>{number = 64, name = (null)}
81:<NSThread: 0x600003a8bd00>{number = 65, name = (null)}
82:<NSThread: 0x600003aafac0>{number = 66, name = (null)}
83:<NSThread: 0x600003abde40>{number = 67, name = (null)}
84:<NSThread: 0x600003a86600>{number = 4, name = (null)}
85:<NSThread: 0x600003a8dec0>{number = 5, name = (null)}
86:<NSThread: 0x600003a98b80>{number = 3, name = (null)}
87:<NSThread: 0x600003aa6380>{number = 9, name = (null)}
88:<NSThread: 0x600003aa66c0>{number = 7, name = (null)}
28:<NSThread: 0x600003aa0000>{number = 12, name = (null)}
90:<NSThread: 0x600003ab1ec0>{number = 10, name = (null)}
29:<NSThread: 0x600003abd080>{number = 13, name = (null)}
31:<NSThread: 0x600003ab1b00>{number = 15, name = (null)}
93:<NSThread: 0x600003aa6000>{number = 11, name = (null)}
94:<NSThread: 0x600003abd100>{number = 14, name = (null)}
34:<NSThread: 0x600003abd1c0>{number = 18, name = (null)}
36:<NSThread: 0x600003aa73c0>{number = 20, name = (null)}
37:<NSThread: 0x600003abd280>{number = 21, name = (null)}
98:<NSThread: 0x600003aa0640>{number = 8, name = (null)}
100:<NSThread: 0x600003aa7440>{number = 16, name = (null)}
99:<NSThread: 0x600003ab30c0>{number = 19, name = (null)}

1.5 串行和同步的区别:串行是按任务添加的先后顺序执行,同步是按代码书写(执行)的顺序执行

  • 在主队列中同步串行会发生死锁,就是因为这个两个执行顺序发生冲突,引起循环等待

1.6 其他实例测试

实例一


实例二


实例三

参考博客:

iOS线程间通信 - GCD篇
iOS线程间通信 - NSThread篇
iOS开发 swift5 – GCD
我的另外一篇博客:GCD

疑问:

1.同步并行会死锁吗
2.同步和串行的区别

iOS 多线程 swift5 GCD 自己消化的相关推荐

  1. iOS 多线程和GCD(Grand Central Dispath) 教程 (一)

    iOS 多线程和GCD(Grand Central Dispath) 教程 (一)  本文翻译自 Ray Wenderlich 的博客 点击打开原文链接.全部由本人亲手翻译...童叟无欺~ 你有木有遇 ...

  2. iOS多线程-【GCD】

    参考链接:https://www.jianshu.com/p/2d57c72016c6 博主总结的很好,个人理解的很清晰 1.GCD简介 因为 GCD 有很多好处啊,具体如下: GCD 可用于多核的并 ...

  3. IOS多线程使用GCD与信号量实现生产者与消费者模式

    一.原理的简述 在生产者消费者模式当中,首先需要分清在这个模式当中有哪些角色? 各角色分别担任什么职责与它们之间的关系如何? 角色之间是在保证数据的准确性的情况下如何通信(同步数据)的? 假设现在有一 ...

  4. iOS 多线程:『GCD』详尽总结

    原文链接:www.jianshu.com/p/2d57c7201- 感谢大家对这篇文章的喜欢和支持.为了不辜负大家的喜欢,也为了更好的让大家了解 iOS 多线程,以及 GCD 的相关知识,我对这篇文章 ...

  5. iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)

    2017-07-08 remember17 Cocoa开发者社区 目的 本文主要是分享iOS多线程的相关内容,为了更系统的讲解,将分为以下7个方面来展开描述. 多线程的基本概念 线程的状态与生命周期 ...

  6. iOS多线程开发之GCD(基础篇)

    总纲: GCD基本概念 GCD如何实现 GCD如何使用 队列和任务组合 一.GCD基本概念 GCD 全称Grand Central Dispatch(大中枢队列调度),是一套低层API,提供了⼀种新的 ...

  7. iOS 多线程-GCD栅栏方法

    iOS 多线程-GCD任务+队列. iOS 多线程-GCD队列组. iOS 多线程-GCD栅栏方法. 上一篇文章记录了队列组的使用,是为了处理多个任务之间的顺序.但是开发中会出现多组任务的顺序问题. ...

  8. iOS 多线程的四种技术方案

    iOS 多线程的四种技术方案 image pthread 实现多线程操作 代码实现: void * run(void *param) {for (NSInteger i = 0; i < 100 ...

  9. iOS多线程:『NSOperation、NSOperationQueue』详尽总结

    2019独角兽企业重金招聘Python工程师标准>>> iOS多线程:『NSOperation.NSOperationQueue』详尽总结 转载: 原地址https://www.ji ...

最新文章

  1. 概率链接nbu 2416 奇怪的散步
  2. 如何了解这个世界(社会)运行的本质
  3. 记一个bug定位与修复过程
  4. leetcode 496, 503, 556. Next Greater Element I, II, III | 496, 503, 556. 下一个更大元素 I,II,III(单调栈)
  5. 教你实践ASP.NET Core Authorization(免看文档教程)
  6. JAVA 1.7并发之LinkedTransferQueue原理理解
  7. 论文解读——Improving Object Detection With One Line of Code
  8. T-SQL语言(一)
  9. 排便的快感--不是非主流
  10. 2014大学计算机操作系统,郑州大学软件学院2013-2014《计算机操作系统》试题及答案...
  11. 分割 反比 权重图 梯度 灰度_numpy gradient梯度函数1
  12. Atitit opencv版本新特性attilax总结
  13. SAM2695 带效果器的低功耗单芯片合成器
  14. Java购票系统实训总结_Java 购票系统实现
  15. 如何使用DOSBox软件编写运行汇编语言程序
  16. java解指派问题,运用Excel规划求解解决指派问题
  17. 最全浏览器兼容性问题以及解决方案
  18. EINT DINT ERTM DRTM EALLOW EDIS ESTOP0的理解
  19. 王可欣作业一 统计软件简介与数据操作
  20. Efficientnet网络详解及构建

热门文章

  1. windows环境C++抓取dump信息
  2. python中的map怎么用_python中的map怎么使用(方法详解)
  3. 公路村村通(含注释)
  4. oracle表如何创建序列,Oracle中如何创建序列
  5. verilog 跨时钟域 单bit延迟打拍 多bit延迟采样 多bit计数延迟采样
  6. 2021-10-18使用eop烧写裸板程序
  7. 新手大战Android源码之启动过程
  8. Flutter 插件signature签字使用
  9. 深度优先搜索详解 C++实现
  10. python随机生成三位数字_五种方法实现python3-随机生成10位包含数字和字母的密码...