主队列:dispatch_get_main_queue()
- 专门用来在主线程上调度任务的队列
- 不会开始线程
- 如果当前主线程正在由任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度
- 可以理解为串行队列(serial),但是它的行为并不完全像常规的串行队列
- 在main()函数创建之前就有主队列了
全局队列:
- 为了方便程序员的使用,苹果提供了全局队列:dispatch_get_global_queue(0, 0)
- 全局队列是一个并发队列(concurrent)
- 在使用多线程开发时,如果对队列没有特殊需求,在执行异步任务时,可以直接使用全局队列
易错例子:
例一:
// 主队列 存在任务就会执行到底
// 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
网友评论