关于GCD的面试题。

写在前面,先说下几个常识:
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-----{number = 1, name = main}
2020-10-22 15:32:03.677728+0800 多线程面试题(居理新房)[23905:2676169] 2:---{number = 1, name = main}
2020-10-22 15:32:03.677847+0800 多线程面试题(居理新房)[23905:2676169] 3----{number = 1, name = main}
2020-10-22 15:32:03.678113+0800 多线程面试题(居理新房)[23905:2676169] 4-----{number = 1, name = main}
2020-10-22 15:32:03.678226+0800 多线程面试题(居理新房)[23905:2676169] 5-----{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-----{number = 1, name = main}
    (lldb)
    造成死锁的原因是,在主线程中默认开启的是串行队列。这其中有三个队列。
    A:viewDidLoad队列。以及B、C队列。队列中的任务顺序是A,B,C。B需要等着A执行完,才会执行。而B队列是同步开启的,需要立即执行,但是B需要A执行完才能执行。
    A执行完的前提是必须执行B中的任务。这样就死锁了。

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

你可能感兴趣的:(关于GCD的面试题。)