ain} 1
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 2
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 3
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 4
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 5
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 6
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 7
2016-02-25 17:18:38.040 test[1979:399667]
{number = 1, name = main} 8
2016-02-25 17:18:38.041 test[1979:399667]
{number = 1, name = main} 9
结论:并发队列,同步执行,不开线程,顺序执行
4.2.4 并发队列,异步执行
代码:
// 1. 创建并发队列
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
// 2. 将任务添加到队列, 并且指定同步执行
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
输出:
2016-02-25 17:22:59.357 test[1992:403694]
{number = 7, name = (null)} 6
2016-02-25 17:22:59.356 test[1992:403684]
{number = 3, name = (null)} 1
2016-02-25 17:22:59.356 test[1992:403689]
{number = 5, name = (null)} 3
2016-02-25 17:22:59.356 test[1992:403683]
{number = 2, name = (null)} 0
2016-02-25 17:22:59.356 test[1992:403692]
{number = 6, name = (null)} 4
2016-02-25 17:22:59.356 test[1992:403693]
{number = 8, name = (null)} 5
2016-02-25 17:22:59.356 test[1992:403695]
{number = 9, name = (null)} 7
2016-02-25 17:22:59.357 test[1992:403688]
{number = 4, name = (null)} 2
2016-02-25 17:22:59.357 test[1992:403694]
{number = 7, name = (null)} 9
2016-02-25 17:22:59.357 test[1992:403696]
{number = 10, name = (null)} 8
结论:开启足够多的线程,不按照顺序执行
CPU在调度的时候以最高效的方式调度和执行任务,所以会开启多条线程,因为并发,执行顺序不一定
5、主队列
5.1 主队列
主队列是系统提供的,无需自己创建,可以通过dispatch_get_main_queue()函数来获取。
5.2 特点
- 添加到主队列的任务只能由主线程来执行。
先进先出的,只有当主线程的代码执行完毕后,主队列才会调度任务到主线程执行
5.3 主队列 异步执行
代码
// 1. 获取主队列
dispatch_queue_t q = dispatch_get_main_queue();
// 2. 将任务添加到主队列, 并且指定异步执行
for (int i = 0; i < 10; i++) {
dispatch_async(q, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
// 先执行完这句代码, 才会执行主队列中的任务
NSLog(@"hello %@", [NSThread currentThread]);
打印
2016-02-25 21:10:43.293 test[773:786816] hello
{number = 1, name = main}
2016-02-25 21:10:43.295 test[773:786816]
{number = 1, name = main} 0
2016-02-25 21:10:43.295 test[773:786816]
{number = 1, name = main} 1
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 2
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 3
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 4
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 5
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 6
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 7
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 8
2016-02-25 21:10:43.296 test[773:786816]
{number = 1, name = main} 9
打印结果得出的一些结论
- 在主线程顺序执行,不开启新的线程
- 主队列的特点:只有当主线程空闲时,主队列才会调度任务到主线程执行
- 主队列就算是异步执行也不会开启新的线程
- 主队列相当于一个全局的串行队列
- 主队列和串行队列的区别
- 串行队列:必须等待一个任务执行完毕,才会调度下一个任务。
- 主队列:如果主线程上有代码执行,主队列就不调度任务。
5.4 主队列 同步执行(死锁)
代码
NSLog(@"begin");
// 1. 获取主队列
dispatch_queue_t q = dispatch_get_main_queue();
// 2. 将任务添加到主队列, 并且指定同步执行
// 死锁
for (int i = 0; i < 10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@ %d", [NSThread curr