面试iOS 90%人可能都会回答错误的一个多线程基础题

这是某大厂的面试原题,我当时第一问回答对了,而后第二问就凉凉了。

题目描述:面试

一问:GCD是同步仍是异步状况会开启多线程swift

答:同步是不会开启新的线程的,异步才会开启新的线程。多线程

这个没啥难度,基本都是必会的。经过代码验证同步在串行队列和并发队列状况下会不会建立新的线程并发

验证代码:异步

dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"(1).=====%@",[NSThread currentThread]);
    dispatch_sync(serialQueue, ^{
      NSLog(@"(2).=====%@",[NSThread currentThread]);
    });
    dispatch_sync(conQueue, ^{
      NSLog(@"(3).=====%@",[NSThread currentThread]);
    });
复制代码

输出结果:async

(1).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
(2).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
(3).=====<NSThread: 0x2837f6f00>{number = 1, name = main}
复制代码

能够看出同步是不会产生新的线程。固然问题确定不会这么简单就结束了。优化


二问:异步必定会开启新的线程吗。spa

答:不会,异步在主队列里不会建立新的线程,在其余串行和并发队列都会建立新的子线程线程

验证代码:code

dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t conQueue = dispatch_queue_create("conQueue", DISPATCH_QUEUE_CONCURRENT);

    NSLog(@"(1).=====%@",[NSThread currentThread]);
    dispatch_async(serialQueue, ^{
      NSLog(@"(2).=====%@",[NSThread currentThread]);
    });
    dispatch_async(conQueue, ^{
      NSLog(@"(3).=====%@",[NSThread currentThread]);
    });
    dispatch_async(mainQueue, ^{
      NSLog(@"(4).=====%@",[NSThread currentThread]);
    });
复制代码

输出结果:

(1).=====<NSThread: 0x2800a6f00>{number = 1, name = main}
(2).=====<NSThread: 0x2800ca5c0>{number = 3, name = (null)}
(3).=====<NSThread: 0x2800ca5c0>{number = 3, name = (null)}
(4).=====<NSThread: 0x2800a6f00>{number = 1, name = main}
复制代码

看结果(1)和(4)能够肯定,在异步主队列确实没有开启新的线程,两个都是main线程,number号为1.

再看(2)和(3),发现确实是建立了新的线程。可是仔细看线程号 发现(2)和(3) 对应的 number 都是3 。 也就是这两个异步动做只建立了一个新的线程。按照常识来讲不是应该建立两个不一样线程吗?

这儿就要从时间和空间谈到GCD对线程调度优化问题了。

GCD在执行多个异步操做的时候,会从时间和空间进行权衡会不会建立新的线程,通常每个任务开启一个线程这样时间最优,可是线程太多会消耗内存空间。因此GCD会自动权衡根据任务分配合适的线程数,从而达到空间和时间的最优。

固然具体GCD是怎么作的,可能须要看源码了...

这是我给这个问题的总结:

  • 同步:不具有开启线程的能力,必定串行执行任务
  • 异步:具备开启线程的能力,可是在主队列里不会开启新的线程。 若是在串行队列和并发队列里开启n个子线程,gcd优化以后未必会真的有n个子线程。
相关文章
相关标签/搜索