dispatch_sync的官方文档中有这么一句话:
As an optimization, this function invokes the block on the current thread when possible.
意思是作为优化手段,如果可以,block会直接在当前线程中执行。
然后写了几段代码测试了下:
dispatch_async(_myQueue1, ^{
NSLog(@"1 start!");
sleep(1);
NSLog(@"1 stop!");
dispatch_async(_myQueue2, ^{
NSLog(@"2 start!");
sleep(2);
NSLog(@"2 stop!");
});
dispatch_sync(_myQueue2, ^{
NSLog(@"3 start!");
sleep(1);
NSLog(@"3 stop!");
});
});
如果_myQueue1,_myQueue2都是自己创建的队列,那3确实是与1在同一线程中执行,2在另外一个线程中执行。但是3虽然与2不在一个线程中,但是由于在同一队列里,所以依然要等待2执行完才能执行3,当前线程会被阻塞知道2、3都执行完。
如果令_myQueue1 = dispatch_get_main_queue(),_myQueue2是自己创建的队列,3就会在主线程中执行。也就是说在主线程中调用dispatch_sync往子线程派发任务,任务会直接在主线程执行。
但如果_myQueue1是自己创建的队列,_myQueue2 = dispatch_get_main_queue(),也就是说在子线程中调用dispatch_sync往主线程派发任务,GCD不会做这种优化,任务会如你所愿在主线程中执行。
以上结论仅仅是简单代码测试得到,有可能在复杂环境下苹果有更为复杂的线程调度策略。大家在使用同步派发时需要自己注意下。
网友评论