美文网首页
串行队列中任务的同步和异步执行

串行队列中任务的同步和异步执行

作者: 小冰山口 | 来源:发表于2018-09-05 01:12 被阅读0次

本人有若干成套学习视频, 可试看! 可试看! 可试看, 重要的事情说三遍 包含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这个串行队列中的任务同步执行的时候, 是不创建新的线程的, 那么任务会在当前线程执行, 即主线程执行, 此时, 主线程中就有serialQueuemainQueue两个队列的任务.

下图为打印结果:

<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

任务A现在在serialQueue串行队列中是排在前面的

任务A在串行队列中

然而, 在serialQueue串行队列中, 还有一个任务B

任务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, 具体原因不知道, 😁

PS. 本人有若干成套学习视频, 包含Java, 数据结构与算法, iOS, 安卓, python, flutter等等, 如有需要, 联系微信tsaievan.

相关文章

  • iOSIN-GCD

    队列和同步异步 区别并行队列串行队列主队列同步(sync)没有开启新线程,串行执行任务没有开启新线程,串行执行任务...

  • GCD学习总结

    GCD容易混淆的概念 任务,同步,异步 ,串行队列,并发队列 任务就是要做的事情 同步和异步是用来执行任务的 串行...

  • GCD小总结

    单例模式 串行队列同步/异步执行任务 并发队列同步/异步执行任务 队列组 延时执行 barrier

  • iOS多线程同步异步、串行并发的个人剖析(GCD)

    先来说一个队列和任务: 队列分为串行和并行 任务的执行分为同步和异步 这两两组合就成为了串行队列同步执行,串行队列...

  • iOS多线程同步异步、串行并发的剖析

    先来说一个队列和任务: 队列分为串行和并行 任务的执行分为同步和异步 这两两组合就成为了串行队列同步执行,串行队列...

  • iOS GCD笔记

    串行队列 并发队列 主队列 全局并发队列 同步执行 异步执行 同步+并发队列 = 没有开启新线程,串行执行任务 s...

  • 队列dispatch_queue的使用

    队列分为:串行队列、并发队列和主队列,主队列也叫特殊串行队列,是GCD自带的。 任务的执行分为:同步执行和异步执行...

  • iOS GCD 串行和并发队列的理解

    首先看串行队列同步异步任务的请求顺序 运行结果 运行结果显示:任务依次执行,异步会创建新线程。 结论:串行队列中的...

  • 多线程

    iOS中的几种多线程GCD1、GCD分为任务和队列,任务(同步,异步)队列(串行,并发),同步串行,同步主队列的情...

  • iOS开发-队列和同步异步执行的结果分析

    多线程中的队列有:串行队列,并发队列,全局队列(并发),主队列(串行)。 执行的方法有:同步执行和异步执行。 提到...

网友评论

      本文标题:串行队列中任务的同步和异步执行

      本文链接:https://www.haomeiwen.com/subject/viqowftx.html