2019.02.20更新:
回看之前的描述自己都看不太明白要论述的问题。现大概整理要点如下:
- 在同一个队列中,才考虑同步和异步
- 不同队列之间执行的任务互不影响
- 队列又分串行队列和并行队列,区别在于同一时间这个队列里有一个线程还是多个线程在执行任务
- 队列中同步或异步执行任务的区别在于提交任务后是否立即返回
以下是学习了别人的文档后,对自己不太理解的知识点的一点总结。
要点:
同步和异步只需要抓住提交任务后是否是立即返回:同步提交任务到队列后不是立即返回(它要留下来执行任务),异步提交任务到队列后立即返回。
串行和并行队列则决定在一个队列中,同一时刻这个队列中是一个线程在执行任务,还是多个线程同时执行任务
注意:
队列之间执行任务并不会相互影响(apple documents: Independent serial queues are processed concurrently with respect to each other.)
知识点:
dispatch_sync(同步)和dispatch_async(异步)的区别——是否立即返回
dispatch_sync:
提交任务到队列后,不是立即返回,而是等到block块中的任务执行完后返回
dispatch_async(什么队列,任务是什么):
提交任务到队列后,立即返回。(apple documents:Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked 也就是说dispatch_async只管提交任务,提交任务给队列后,就马上返回到了主线程中。那么执行任务的事就交给了队列。也就可以理解为什么多个队列之间是相互独立的了)
dispatch_async参数:
第一个参数:在什么队列中执行
Serial Queue:串行队列。同一时刻,只能执行该队列中的一个任务,不管有几个线程。
Concurrent Queue:并行队列。同一时刻,可以执行该队列中的多个任务。
第二个参数:在block中实现想要做的
补充知识:block中的代码(block的实现部分)执行特点
程序并不是遇到block的实现部分就立刻进入block块中执行里面的代码,而是在程序的其他地方(在这里就是apple官方事先写在了某个方法中,专业点叫回调)调用这个block时才执行(block和函数指针一样,block的实现部分得在调用block之前,否则调用也没有意义)
测试实例:
- (void)test1{
dispatch_async(serial串行队列 A,block块{
循环打印 '-'; //注意:这里面的代码是由serial串行队列中的线程来执行的
});
dispatch_async(serial串行队列B ,block块{
循环打印 '+'; //注意:这里面的代码是由另一个serial串行队列中的线程来执行的
});
循环打印 '*'; //注意:这里的代码是在主线程中的,而主线程没有在serial队列中
}
特别注意:
主线程并没有在serial队列中,而是在主队列中,也就是说存在三个队列,主队列(dispatch_get_main_queue)和两个serial queu队列,那同一时刻程序就会至少执行三个任务:一个是主队列中的,两个serial 队列各执行一个。
运行结果:
程序会穿插打印*、- 和+号,也就是说:虽然我们用的是serial串行队列(一次只能执行一个任务),但是程序却同时执行了多个任务(因为程序并不是将*或者+中的一个完全打印完后再打印另一个,而是穿插打印)。也就说明了队列之间是执行任务是互不影响的
一点结论:
同步和异步只是相对同一个队列来说的,决定这个队列中同一时刻有几个线程在执行任务;
如果有两个或者多个队列,即使都是串行队列,同一时刻,每个队列会独立的执行各自队列中的任务,也就是说,程序在同一时刻会执行多个任务。