同步与异步、串行与并发

作者: isletn | 来源:发表于2017-06-21 17:30 被阅读0次

说到多线程,我们必须明白两个概念:线程与队列。我把线程理解为车间的流水线,而队列则决定了每条流水线的工作方式。我们可以往队列中加入任务,并决定该队列在什么线程执行。

主队列异步执行

    DispatchQueue.main.async {
        print(Thread.current)
        DispatchQueue.main.async {
            print(Thread.current)
            sleep(2)
            print(1)
        }
        print(2)
        DispatchQueue.main.async {
            print(Thread.current)
            print(3)
        }
        sleep(1)
    }
  • 打印结果:
主队列异步执行.png
  • 分析:上述代码看似异步执行开了子线程,实则不然,DispatchQueue.main.async实际上队列中的任务还是在主线程执行,也就是同步执行。而它与DispatchQueue.main.sync的区别就是它不会造成死锁。
    由于主队列是串行队列,根据先进先出的原则,上述代码的执行顺序是:将sleep(2)print(1)加入队列->print(2)->将print(3)加入队列->sleep(1)->sleep(2)->print(1)->print(3)

串行队列异步执行

    let serialQueue = DispatchQueue(label: "serial_queue")
    serialQueue.async {
        print(Thread.current)
        serialQueue.async {
            sleep(2)
            print(Thread.current)
            print(1)
        }
        print(2)
        serialQueue.async {
            print(3)
            print(Thread.current)
        }
        sleep(1)
    }
  • 打印结果:


    串行队列异步执行.png
  • 分析:为什么要自定义串行队列与主队列分开来?我们知道主队列就是一个串行队列,而它与普通串行队列在异步执行时有什么区别呢?我们可以尝试打印各个线程中的Thread.current,从结果可以看出,自定义串行队列在异步执行时是创建了支线程的,且因为串行的原因只会创建一个支线程。
    同是串行队列,它的执行顺序同上。

并发队列异步执行

    let concurrentQueue = DispatchQueue(label: "concurrent_quque", attributes: .concurrent)
    concurrentQueue.async {
        print(Thread.current)
        concurrentQueue.async {
            print(Thread.current)
            sleep(2)
            print(1)
            print(4)
            print(5)
            print(6)
            print(7)
        }
        print(2)
        concurrentQueue.async {
            print(Thread.current)
            print(3)
        }
        sleep(1)
    }

  • 打印结果:
并发队列异步执行.png
  • 分析:从结果可以看出,并发队列异步执行会开多个线程,其数量等于concurrentQueue.async的调用次数。
    并发队列的特点是它在异步执行时,队列中的任务可以无限接近同时执行。那么问题来了:经过试验,无论我打印多少次,这两段代码都没有体现出并发执行的特性,因为它打结果并没有发生改变。
    image.png
    再观察一下代码,可以发现:第一段异步执行代码中sleep(2)让线程睡了2s,我们把它注释。
    image.png
    多打印几次:
    image.png
    image.png
    因为print(Thread.current)也算一个任务,我们注释掉。
    image.png
    image.png

结论:

  • 对于主队列,同步、异步执行都不会开线程;
  • 对于主队列以外的队列,同步执行不会开线程,异步执行会开线程;
  • 一般来说,开线程的数量取决于.async的调用次数;
  • 无论是串行还是并发,队列中的任务在一个async{ }中都是顺序执行的;
  • 任务并发是指并发队列在异步执行时多个async{ }中的任务无限接近同时执行。

相关文章

  • 多线程处理(问题使用方法)

    一、同步与异步、串行与并发: 首先我们要明白:什么是同步、异步?什么是并发、串行?同步、异步是提交任务的一种方式,...

  • ios GCD概述

    GCD 容易混淆的术语 同步/异步/并发/串行 同步和异步: 决定要不要开启新的线程 并发与串行 决定了任务的执行...

  • 同步、异步与串行、并发

    1、同步、异步描述的是当前线程或代码流是否要阻塞以等待加入队列的任务执行完毕;同步要阻塞当前线程,异步不会阻塞当前...

  • 同步与异步、串行与并发

    说到多线程,我们必须明白两个概念:线程与队列。我把线程理解为车间的流水线,而队列则决定了每条流水线的工作方式。我们...

  • 多线程

    GCD NSOperation NSThread 多线程与锁 一、GCD 同步、异步 和 串行、并发 dispat...

  • 第九篇:Objective-C 知识回顾多线程

    9.1.同步/异步 和 串行/并发 问题一:同步/异步 和 串行/并发组合有哪些? dispatch_sync(s...

  • GCD的几种创建方式及基本使用

    同步函数 同步函数+主队列 同步函数+串行队列 同步函数+并发队列 异步函数 异步函数+主队列 异步函数+串行队列...

  • 多线程GCD笔记

    同步函数 + 主队列 异步函数 + 主队列 同步函数 + 串行队列 异步函数 + 串行队列 同步函数 + 并发队列...

  • GCD 死锁

    GCD死锁 同步 异步 串行 并发

  • 关于GCD总结

    什么是GCD 理解串行、并发及同步异步 串行和并发 同步和异步 队列 串行队列 两者等效.2)使用主队列(在主队列...

网友评论

    本文标题:同步与异步、串行与并发

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