本人有若干成套学习视频, 可试看! 可试看! 可试看, 重要的事情说三遍 包含Java
, 数据结构与算法
, iOS
, 安卓
, python
, flutter
等等, 如有需要, 联系微信tsaievan
.
- 串行队列同步执行
let serialQueue = DispatchQueue(label: "dispatch_demo.tsaievan.com")
let mainQueue = DispatchQueue.main
let sAdd = String(format: "%p", serialQueue)
let mAdd = String(format: "%p", mainQueue)
serialQueue.sync {
print("\(Thread.current)========1==== sAdd = \(sAdd)===== mAdd = \(mAdd)")
}
print("\(Thread.current)========2")
serialQueue.sync {
print("\(Thread.current)========3")
}
print("\(Thread.current)========4")
如上图所示, serialQueue
是我创建的串行队列, 而mainQueue
是主队列, 当serialQueue
这个串行队列中的任务同步执行的时候, 是不创建新的线程的, 那么任务会在当前线程执行, 即主线程执行, 此时, 主线程中就有serialQueue
和mainQueue
两个队列的任务.
下图为打印结果:
<NSThread: 0x60c00006c4c0>{number = 1, name = main}========1==== sAdd = 0x608000144410===== mAdd = 0x1057a1e80
<NSThread: 0x60c00006c4c0>{number = 1, name = main}========2
<NSThread: 0x60c00006c4c0>{number = 1, name = main}========3
<NSThread: 0x60c00006c4c0>{number = 1, name = main}========4
- 串行队列异步执行
serialQueue.async {
print("\(Thread.current)========1==== sAdd = \(sAdd)===== mAdd = \(mAdd)")
}
print("\(Thread.current)========2")
serialQueue.async {
print("\(Thread.current)========3")
}
print("\(Thread.current)========4")
串行队列异步执行会开新的线程, 但只会开一条新的线程.
上面的代码, 情况是这样的, serialQueue
放到子线程中去执行了,
print("\(Thread.current)========2")
print("\(Thread.current)========4")
这两句代码还是在主线程/主队列中执行的
但serialQueue
虽然在子线程中执行, 但也遵循FIFO(先进先出)的策略, 所以:
print("\(Thread.current)========1==== sAdd = \(sAdd)===== mAdd = \(mAdd)")
这个任务一定是先于
print("\(Thread.current)========3")
这个任务的
打印顺序如下:
<NSThread: 0x600000064c00>{number = 1, name = main}========2
<NSThread: 0x60400026d980>{number = 3, name = (null)}========1==== sAdd = 0x60c000158cb0===== mAdd = 0x10e704e80
<NSThread: 0x600000064c00>{number = 1, name = main}========4
<NSThread: 0x60400026d980>{number = 3, name = (null)}========3
当然, 也有可能是(2134) (1234)(1243)(2143)(2413)等
- 串行异步中嵌套同步
print("\(Thread.current)========1")
serialQueue.async {
print("\(Thread.current)========2")
serialQueue.sync {
print("\(Thread.current)========3")
}
print("\(Thread.current)========4")
}
print("\(Thread.current)========5")
这样的情况会造成 死锁
死锁首先, serialQueue
异步执行, 开启了新的线程, 在这个serialQueue
串行队列中有一任务, 见下图:
我们把整个这个任务叫做任务A
任务A现在在serialQueue
串行队列中是排在前面的
然而, 在serialQueue
串行队列中, 还有一个任务B
所以A和B在串行队列中的顺序如下图所示:
任务B在串行队列中
也就是A执行完了再执行B, 但是B是同步的, 也就是线程阻塞的, 必须等到B执行完了A任务才能执行完, 所以A在等待B执行完毕, 但B又在等待A执行完毕, 这样就造成了死锁, B永远无法执行, A也无法执行完毕
所以打印结果是:
<NSThread: 0x60c000076240>{number = 1, name = main}========1
<NSThread: 0x60c000076240>{number = 1, name = main}========5
<NSThread: 0x60c00007c7c0>{number = 3, name = (null)}========2
然后程序崩溃!
- 串行同步中嵌套异步
print("\(Thread.current)========1")
serialQueue.sync {
print("\(Thread.current)========2")
serialQueue.async {
print("\(Thread.current)========3")
}
print("\(Thread.current)========4")
}
print("\(Thread.current)========5")
这种情况是不会造成死锁的
串行同步中嵌套异步 由于红色方框内的任务, 你可以看成是任务A, 任务A是分配在主线程中的, 任务B
而蓝色方框的任务B是分配在子线程中的, 所以不会造成线程上的阻塞
所以主线程的顺序一定是, 1,2,4,5
而打印3这个任务由于处于子线程, 所以会放在打印2之后的任意位置,
所以可能的顺序有12345,12435,12453
实际打印几乎全部是12453, 具体原因不知道, 😁
网友评论