iOS面试知识点iOS底层基础知识程序员

iOS 主队列和全局队列的区别

2019-01-19  本文已影响97人  wp_Demo
主队列:dispatch_get_main_queue()
  1. 专门用来在主线程上调度任务的队列
  2. 不会开始线程
  3. 如果当前主线程正在由任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度
  4. 可以理解为串行队列(serial),但是它的行为并不完全像常规的串行队列
  5. 在main()函数创建之前就有主队列了
全局队列:
  1. 为了方便程序员的使用,苹果提供了全局队列:dispatch_get_global_queue(0, 0)
  2. 全局队列是一个并发队列(concurrent)
  3. 在使用多线程开发时,如果对队列没有特殊需求,在执行异步任务时,可以直接使用全局队列

易错例子:

例一:
    // 主队列 存在任务就会执行到底
    // dispatch_get_main_queue() -->
    NSLog(@"0");
    // 等
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"1");
    });
    NSLog(@"2");

例一的打印结果绘制造成程序直接崩溃,因为造成了死锁.
造成死锁的原因:
全局队列在可以理解为串行队列,这里又创建了一个同步线程,这个同步线程在等待主线程执行 完毕,而主队列在扥带同步线程执行完毕,所以他们两个就是互相在等对方结束,这么就造成了死锁.

例二:
    __block int a = 0;
    while (a<5) {
        NSLog(@"进来的时候 a = %d",a);
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"%@===%d",[NSThread currentThread],a);
            a++;
        });
    }
    NSLog(@"%@****%d",[NSThread currentThread],a);

分析:
while循环内部有一个异步线程,而这个异步线程放在全局队列中了,我们不知道异步线程什么时候执行a++,所以while就会一直循环,直到a<5,然后才会执行到最后的打印

进来的时候 a = 0
进来的时候 a = 0
<NSThread: 0x600001599ac0>{number = 3, name = (null)}===0
进来的时候 a = 0
<NSThread: 0x600001599b00>{number = 4, name = (null)}===0
进来的时候 a = 1
<NSThread: 0x600001599ac0>{number = 3, name = (null)}===1
进来的时候 a = 2
<NSThread: 0x600001599b00>{number = 4, name = (null)}===2
进来的时候 a = 3
<NSThread: 0x600001599ac0>{number = 3, name = (null)}===3

进来的时候 a = 4
<NSThread: 0x600001599b00>{number = 4, name = (null)}===4
<NSThread: 0x6000015f2940>{number = 1, name = main}****5
<NSThread: 0x600001599ac0>{number = 3, name = (null)}===5

上一篇 下一篇

猜你喜欢

热点阅读