• Objective-C iOS多线程之GCD深入理解


    在 GCD 中,加入了两个非常重要的概念:任务和队列
    一个线程是可以拥有多个执行队列的,所有任务是添加到队列中等待执行的
    主队列是特殊的串行队列,自己创建的队列可以指定串行或并行,全局队列是并行队列

    任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。
    任务有两种执行方式: 同步执行和异步执行,他们之间的区别主要在于会不会阻塞当前线程

    首先看下面这两个例子:

    1、

    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
    NSLog(@"%d",[[NSThread currentThread] isMainThread]);
    });
    

    2、

    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
    NSLog(@"%d",[[NSThread currentThread] isMainThread]);
    });
    

    两个例子都是创建一个新队列,之间的区别只在于前者是以同步运行,后者则是异步
    结果前者打印出1,后者则是0。

    我们分析一下,这里同步的意思其实是对于线程的所有执行队列而言,就是说同步执行时,除了block任务,在同一个线程执行的其他队列全部暂停执行,当block任务执行完成后,其他队列任务才恢复执行。(这里还有个要特别注意的,就是系统在判别是否要暂停队列的执行时,是按照block任务是否在队列头,如果不是就停止队列执行

    上面例子1中创建一个新队列,block任务在第一个,即队列头,以同步执行时就是所有在主线程执行的队列会暂停执行(除了block任务所在队列)。例子2因为是创建一个新队列,又是异步执行,所以会创建一个新线程执行,所以打印出来的0,也就是主线程上的队列照常执行。

    为了证明我上面的假设,我举个例子:

    3、

    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue, ^{
    NSLog(@"%d",[[NSThread currentThread] isMainThread]);
    });
    

    4、

    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_async(queue, ^{
    NSLog(@"%d",[[NSThread currentThread] isMainThread]);
    });
    

    上面两个例子都是将block任务添加到主队列,但是结果却不同,例子3结果是永远不会执行打印语句,程序不会再执行了,例子4正常执行,且在主队列中
    结论:不是异步就一定会开启新的线程

    例子3因为将block任务添加到主队列中,此时主队列还有任务(viewDidLoad没有执行完,所以block任务不是将要执行的任务),根据前面的系统判定,主队列被暂停执行,此时前面的任务无法完成,后面的block任务也无法完成,造成死循环
    例子4中将任务添加到主队列中,虽然是异步操作,但是并不会开启新的线程,因为在主队列中,要在主线程中执行,而异步操作不会将线程阻塞,所以队列照常执行。

    结论:同步会让系统判定暂停执行所有不以block块任务为第一任务的队列(即如果block块任务不在队列头,那么block块任务所在的队列也会暂停执行),且同步一定不会开启新线程,因为GCD觉得既然其它队列暂停执行,block块任务就可以在当前线程执行了,没有必要开启新线程。而异步则系统不会进行判定,但是不一定会开启新线程,这个跟队列有关,如果是新创建的队列,那么GCD就会开启新线程,如果加入已有的队列,那么就会在队列所在的线程中执行。

    简单来讲,同步操作那么block块任务会在当前线程中执行,比如上面在主线程中进行同步操作,那么一定就是在主线程中执行,不管队列是主队列还是全局队列或者自己创建的队列。如果是异步操作的话,那么就要分情况来看了,如果是主队列,那么就是在主线程中执行,如果是全局或自己创建的队列,那么就是在新创建的线程中执行,全局队列会根据任务自动创建一个或多个线程,自己创建的队列就是根据参数设定和任务进行分配。


    至于串行和并行,串行和并行是针对同一个队列中的任务而言的,当使用串行,那么队列里的那么队列里的任务最多只能使用一个线程运行,即同一时刻只有一个任务在执行,如果是并行,那么系统会根据队列里的任务自动分配线程执行,最大线程数根据参数设定


    转载请注明:作者SmithJackyson

  • 相关阅读:
    递归算法介绍及Java应用实战
    常用缓存淘汰算法(LFU、LRU、ARC、FIFO、MRU)
    阿里巴巴高级Java面试题(首发,70道)
    2017阿里技术年度精选(全)
    10年老兵给程序员的10条建议!
    8条关于Web前端性能的优化建议
    (16)约束
    (15)oracle序列
    (14)oracle数据字典
    (13)oracle导出、导入
  • 原文地址:https://www.cnblogs.com/smithjackyson/p/5262123.html
Copyright © 2020-2023  润新知