标签:
首先要确定:一个线程只能执行一个任务,执行完才会执行另一个任务
同步和异步
dispatch_sync 是同步的方式执行任务
dispatch_async 是异步的方式执行任务
同步和异步的区别
同步:在当前线程中执行(不会开辟新线程,是在当前线程执行,一般使用同步执行任务会立马执行,‘写了跟没写一样’)
异步:在另一条新的线程中执行(把任务放在主队列里,但是不需要马上执行)
串行队列和并行队列
串行队列:一个一个执行,就算在异步执行的时候,也只会开辟一条新线程(如果主线程是数字是1,那串行队列只会开辟出一个数字2的线程),并且所有的任务都会在新的线程中执行
dispatch_queue_t queue = dispatch_queue_create(“label”, DISPATCH_QUEUE_SERIAL);
或者
dispatch_queue_t queue = dispatch_queue_create(“label”, NULL); 这两种的创建方式是一样的 程序中会经常写成NULL;
并行队列:在异步执行时会开辟很多新的线程,可以同时执行多个任务,顺序是程序员无法控制的
dispatch_queue_t queue = dispatch_queue_create(“label”, DISPATCH_QUEUE_CONCURRENT);
并发队列的同步执行,不开辟新线程,一步一步执行任务
GCD 主线程
1. 专门在主线程上调度任务
2. 不会开辟新线程,不管同步异步执行,只能在主线程上顺序执行
主线程的异步执行任务
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [self gcdText5]; } - (void)gcdText5 { // 1.获得主线程 dispatch_queue_t queue = dispatch_get_main_queue(); NSLog(@"1-------"); // 2.异步执行任务 // 把任务放在主队列里,但是不需要马上执行 for (int i = 0; i < 10; i++) { NSLog(@"调度前-----"); // 任务:block dispatch_async(queue, ^{ NSLog(@"%@, %d", [NSThread currentThread], i); }); NSLog(@"睡会"); [NSThread sleepForTimeInterval:2.0]; } NSLog(@"完成"); }
这是运行顺序是如下图
2016-05-29 17:09:24.945 GCD[6702:82350] 1------- 2016-05-29 17:09:24.946 GCD[6702:82350] 调度前----- 2016-05-29 17:09:24.946 GCD[6702:82350] 睡会 2016-05-29 17:09:26.951 GCD[6702:82350] 调度前----- 2016-05-29 17:09:26.951 GCD[6702:82350] 睡会 2016-05-29 17:09:28.954 GCD[6702:82350] 调度前----- 2016-05-29 17:09:28.954 GCD[6702:82350] 睡会 2016-05-29 17:09:30.959 GCD[6702:82350] 调度前----- 2016-05-29 17:09:30.959 GCD[6702:82350] 睡会 2016-05-29 17:09:32.963 GCD[6702:82350] 调度前----- 2016-05-29 17:09:32.964 GCD[6702:82350] 睡会 2016-05-29 17:09:34.969 GCD[6702:82350] 调度前----- 2016-05-29 17:09:34.969 GCD[6702:82350] 睡会 2016-05-29 17:09:36.971 GCD[6702:82350] 调度前----- 2016-05-29 17:09:36.971 GCD[6702:82350] 睡会 2016-05-29 17:09:38.971 GCD[6702:82350] 调度前----- 2016-05-29 17:09:38.971 GCD[6702:82350] 睡会 2016-05-29 17:09:40.974 GCD[6702:82350] 调度前----- 2016-05-29 17:09:40.974 GCD[6702:82350] 睡会 2016-05-29 17:09:42.977 GCD[6702:82350] 调度前----- 2016-05-29 17:09:42.977 GCD[6702:82350] 睡会 2016-05-29 17:09:44.981 GCD[6702:82350] 完成 2016-05-29 17:09:44.981 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 0 2016-05-29 17:09:44.982 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 1 2016-05-29 17:09:44.982 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 2 2016-05-29 17:09:44.982 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 3 2016-05-29 17:09:44.982 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 4 2016-05-29 17:09:44.982 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 5 2016-05-29 17:09:44.983 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 6 2016-05-29 17:09:44.983 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 7 2016-05-29 17:09:44.983 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 8 2016-05-29 17:09:44.983 GCD[6702:82350] <NSThread: 0x7ffddb501290>{number = 1, name = main}, 9
为什么会产生这种效果呢
因为异步执行只是把任务放在队列中,不会马上执行,因为主队列的特殊性又不能开辟新的线程,所以会等到主线程的任务执行完才会执行队列中的任务 , 如图
此时主线程正在执行gcdText5这个任务,
当gocText5任务执行完成后在执行 绿色的0,1任务
主线程的同步执行任务
只需要将代码
dispatch_async
换成
dispatch_sync
就可以了,这是运行效果回事这样的
这是因为
同步任务要马上执行,但是线程没空,线程正在执行gcdText5,需要等gcdText5执行完,但是gcdText5在等这个同步任务执行结束,所以会造成主线程阻塞,产生死锁
标签:
原文地址:http://www.cnblogs.com/menglingxu/p/5539878.html