参考:http://ios.jobbole.com/82622/
案例一
NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3
//打印结果:
1
分析:dispatch_sync 执行后,会同步任务(即先阻塞当前线程,优先在任务1所在线程执行当前的任务,而把任务2插入到main_queue尾部),所以任务2执行完了才会执行任务3。而任务2是针对main_queue的,只有等main_queue都执行完了才会执行任务2,而main_queue是串行队列,所以只有任务3完成后才会执行任务2。双方同时进入等待状态,造成死锁。
案例二
NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3
//打印结果:
1
2
3
分析:任务2在会在主线程优先执行任务2,故任务2执行完了才会执行任务3。同时任务2是插入到global队列尾部。所以理所当然的,先执行了2,再执行3。
案例三
dispatch_queue_t queue = dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"1"); // 任务1
dispatch_async(queue, ^{
NSLog(@"2"); // 任务2
dispatch_sync(queue, ^{
NSLog(@"3"); // 任务3
});
NSLog(@"4"); // 任务4
});
NSLog(@"5"); // 任务5
//打印结果:
1
5
2
// 5和2的顺序不一定
分析:这个案例没有使用系统提供的串行或并行队列,而是自己通过dispatch_queue_create函数创建了一个DISPATCH_QUEUE_SERIAL的串行队列。
执行任务1;
- 遇到异步线程,将【任务2、同步线程、任务4】加入串行队列中。因为是异步线程,所以在主线程中的任务5不必等待异步线程中的所有任务完成;
- 因为任务5不必等待,所以2和5的输出顺序不能确定;
- 任务2执行完以后,遇到同步线程,这时,将任务3加入串行队列;
- 又因为任务4比任务3早加入串行队列,所以,任务3要等待任务4完成以后,才能执行。但是任务3所在的同步线程会阻塞,所以任务4必须等任务3执行完以后再执行。这就又陷入了无限的等待中,造成死锁。
案例四
NSLog(@"1"); // 任务1
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"2"); // 任务2
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"3"); // 任务3
});
NSLog(@"4"); // 任务4
});
NSLog(@"5"); // 任务5
//打印结果:
1
2
5
3
4
// 5和2的顺序不一定
分析:
1.执行任务1。
2.多线程执行任务2,主线程执行任务5,前后可能随机。
3.任务3执行的时候,因为是同步,所以会先阻塞global线程,然后把任务3插入到主线程后面,等待主线程执行完了,再执行任务3。
4.任务3执行完,任务4所在的global线程阻塞结束,所以最后执行任务4。
如果在任务5前面加一个,sleep(3); 那么结果依然是这个。任务3会一直等待任务5,任务4也会一直等待任务3。
案例五
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3
});
NSLog(@"4"); // 任务4
while (1) {
}
NSLog(@"5"); // 任务5
打印结果:
1
4
// 1、4顺序不一定
分析略,见案例四分析。