美文网首页
关于GCD的面试题。

关于GCD的面试题。

作者: 早起的大艺术家 | 来源:发表于2020-10-22 15:58 被阅读0次

    写在前面,先说下几个常识:
    1、同步线程不具备开启新线程的能力。异步线程具备开启新线程的能力。
    2、同步线程立即执行任务,异步线程不需要立即执行任务。
    3、同一个串行队列中的任务按照FIFO(先进先出)的顺序执行。
    4、同一个并发队列中的任务,可以并发执行(可同时执行多个)。
    5、在GCD中线程包含队列,队列包含任务。
    以下是昨天遇到的面试题。打的结果是什么。

    • (void)viewDidLoad {
      [super viewDidLoad];
      dispatch_queue_t concurrentQ = dispatch_queue_create("con", DISPATCH_QUEUE_CONCURRENT);
      NSLog(@"1-----%@",[NSThread currentThread]);
      dispatch_sync(concurrentQ, ^{
      NSLog(@"2:---%@",[NSThread currentThread]);
      dispatch_sync(concurrentQ, ^{
      NSLog(@"3----%@",[NSThread currentThread]);
      });
      NSLog(@"4-----%@",[NSThread currentThread]);

      });
      NSLog(@"5-----%@",[NSThread currentThread]);

    }

    正确答案
    2020-10-22 15:32:03.677522+0800 多线程面试题(居理新房)[23905:2676169] 1-----<NSThread: 0x60000157c200>{number = 1, name = main}
    2020-10-22 15:32:03.677728+0800 多线程面试题(居理新房)[23905:2676169] 2:---<NSThread: 0x60000157c200>{number = 1, name = main}
    2020-10-22 15:32:03.677847+0800 多线程面试题(居理新房)[23905:2676169] 3----<NSThread: 0x60000157c200>{number = 1, name = main}
    2020-10-22 15:32:03.678113+0800 多线程面试题(居理新房)[23905:2676169] 4-----<NSThread: 0x60000157c200>{number = 1, name = main}
    2020-10-22 15:32:03.678226+0800 多线程面试题(居理新房)[23905:2676169] 5-----<NSThread: 0x60000157c200>{number = 1, name = main}

    解:
    1、因为是dispatch_sync(同步),所以没有开启新的线程,以下所有任务全部在主线程中执行。{number = 1, name = main}。
    2、因为是DISPATCH_QUEUE_CONCURRENT并发队列,所以队列中的多个任务可以并发执行。
    3、因为是同步,所以立即执行。
    综上所述:上面代码,有一个线程(主线程),两个队列,主线程默认开启一个队列A队列,手动创建了一个并发队列B队列。
    暂且看做A队列中的任务是1,5,B队列中的任务是2、3、4。
    所以A和B是互不影响的两个队列。打印1之后,因为是同步会立即执行B队列中的任务,打印2;因为同步,并且是并发队列,所以会立即执行3,然后打印4。最后打印5.

    如果以上代码改为

    • (void)viewDidLoad {
      [super viewDidLoad];
      dispatch_queue_t mainQ = dispatch_get_main_queue();
      NSLog(@"1-----%@",[NSThread currentThread]);
      dispatch_sync(mainQ, ^{ B队列
      NSLog(@"2:---%@",[NSThread currentThread]);
      dispatch_sync(mainQ, ^{C队列
      NSLog(@"3----%@",[NSThread currentThread]);
      });
      NSLog(@"4-----%@",[NSThread currentThread]);

      });
      NSLog(@"5-----%@",[NSThread currentThread]);
      }
      打印结果:
      2020-10-22 15:49:27.569714+0800 多线程面试题(居理新房)[23932:2687223] 1-----<NSThread: 0x600002774080>{number = 1, name = main}
      (lldb)
      造成死锁的原因是,在主线程中默认开启的是串行队列。这其中有三个队列。
      A:viewDidLoad队列。以及B、C队列。队列中的任务顺序是A,B,C。B需要等着A执行完,才会执行。而B队列是同步开启的,需要立即执行,但是B需要A执行完才能执行。
      A执行完的前提是必须执行B中的任务。这样就死锁了。

    下次回答这类面试题前,先想好线程,队列,任务的关系。

    相关文章

      网友评论

          本文标题:关于GCD的面试题。

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