开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序
关键:因为同步,则不会开新线程,直接使用主线程,
虽然是并发队列,但由于可有一个执行路线,所以会顺序执行
供所有app使用的全局队列
全局队列与 并行队列的3点区别:
1、全局队列不需create、只要get就可以得到
2、全局队列没有名字,因此,调试时,不方便查看
3、全局队列与并行队列的执行效果完全相同
// // ViewController.m // GCD // // Created by xss on 14-11-23. // Copyright (c) 2014年 beyond. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // [self gcd_serial_async]; // [self gcd_serial_sync]; // [self gcd_concurrent_async]; // [self gcd_concurrent_sync]; // [self gcd_concurrent_sync_async]; // [self gcd_concurrent_async_sync]; // [self gcd_serial_sync_async]; // [self gcd_global_queue]; // [self gcd_main_queue_sync]; [self gcd_main_queue_async]; } /* 1、主队列 + 异步dispatch (无论如何dispatch,只要加入主队列,都将串行执行,统一由主队列顺序安排) */ - (void)gcd_main_queue_async { dispatch_queue_t mainQueue = dispatch_get_main_queue(); // 快速向 主队列 里面异步添加10个block for (int i = 0; i<10; i++) { dispatch_async(mainQueue, ^{ NSLog(@"\n---------->异步分派:%@--正在执行 主队列 中的第 %d 个block",[NSThread currentThread],i); }); } } /* 1、主队列 + 同步dispatch == 永远不被执行 因为 主队列 一直有一个block 在监听并处理 UI操作,一直阻塞,不会退出,不会完结 因此,同步dispatch的,排在其后面的block永远不会被执行 */ - (void)gcd_main_queue_sync { dispatch_queue_t mainQueue = dispatch_get_main_queue(); NSLog(@"before"); dispatch_sync(mainQueue, ^{ NSLog(@"永远也不会被执行到"); }); NSLog(@"after"); } /* 供所有app使用的全局队列 全局队列 与 并行队列的一点点区别: 1、全局队列 不需create、只要get就可以得到 2、全局队列 没有名字,因此,调试时,不方便查看 3、全局队列 与并行队列的执行效果完全相同 */ - (void)gcd_global_queue { dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 快速向队列里面同步添加10个block for (int i = 0; i<10; i++) { dispatch_sync(globalQueue, ^{ NSLog(@"\n---------->同步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i); }); } // 快速向队列里面异步添加10个block for (int i = 0; i<10; i++) { dispatch_async(globalQueue, ^{ NSLog(@"\n---------->异步分派:%@--正在执行全局队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 并行队列:先异步分派10个,再同步分派10个 总结:穿插执行 */ - (void)gcd_concurrent_async_sync { dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT); // 快速向队列里面异步添加10个block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } // 快速向队列里面同步添加10个block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 并行队列:分同步分派10个,再异步分派10个 */ - (void)gcd_concurrent_sync_async { dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT); // 快速向队列里面同步添加10个block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } // 快速向队列里面异步添加10个block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 串行队列: 1.先sync分派10个block 2.再async分派10个block */ - (void)gcd_serial_sync_async { dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL); // 快速向队列里面添加10个block for (int i = 0; i<10; i++) { // 同步dispatch dispatch_sync(queue, ^{ NSLog(@"---------->同步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i); }); } // 快速向队列里面添加10个block for (int i = 0; i<10; i++) { // 异步dispatch dispatch_async(queue, ^{ NSLog(@"---------->异步分派:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 并发队列+同步dispatch 关键:同步,则不会开新线程,直接使用主线程, 虽然是并发队列,但由于 可有一个执行路线,所以会顺序执行 */ - (void)gcd_concurrent_sync { // 参数1:是调试用的,是C字符串, // 参数2:A dispatch queue that may invoke blocks concurrently and supports // barrier blocks submitted with the dispatch barrier API. dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT); // 快速向队列里面添加10个block for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->同步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 并发队列+异步dispatch 关键:开多条新线程(具体开几个无法控制),block执行没有顺序,程序员无法控制执行顺序 */ - (void)gcd_concurrent_async { // 参数1:是调试用的,是C字符串, // 参数2:A dispatch queue that may invoke blocks concurrently and supports // barrier blocks submitted with the dispatch barrier API. dispatch_queue_t queue = dispatch_queue_create("并行队列", DISPATCH_QUEUE_CONCURRENT); // 快速向队列里面添加10个block for (int i = 0; i<10; i++) { dispatch_async(queue, ^{ NSLog(@"\n---------->异步分派:%@--正在执行并行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 串行队列 + 同步dispatch 【极少使用】 既然是 同步dispatch,就没有必要开一条新线程,在主线程上 一个接一个block执行 */ - (void)gcd_serial_sync { // 参数1:是调试用的,是C字符串, // 参数2:A dispatch queue that invokes blocks serially in FIFO order. dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL); // 快速向队列里面添加 for (int i = 0; i<10; i++) { dispatch_sync(queue, ^{ NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i); }); } } /* 1、串行队列里面的异步任务 这个非常有用,举例如下: 一个串行的队列里,先执行 下载图片的block 然后再执行滤镜操作(如 红眼、高光、羽化等blcok) 最后再执行保存block */ - (void)gcd_serial_async { // 参数1:是调试用的,是C字符串, // 参数2:A dispatch queue that invokes blocks serially in FIFO order. dispatch_queue_t queue = dispatch_queue_create("串行队列", DISPATCH_QUEUE_SERIAL); // 快速向队列里面添加 for (int i = 0; i<10; i++) { // Submits a block for asynchronous execution on a dispatch queue. // Calls to dispatch_async() always return immediately after the block has // been submitted, and never wait for the block to be invoked. dispatch_async(queue, ^{ NSLog(@"\n---------->线程:%@--正在执行串行队列中的第 %d 个block",[NSThread currentThread],i); }); } } @end
串行队列: 同步里面 嵌套了同步,结果是:【永远也不会执行】
因为:理论上 是在主线程 执行完 第一个block,再执行 被添加到queue里面的第2个block,但是:由于 第1个block没执行完,是不会执行 后来添加到queue里面的第2个block,因此阻塞住了,第2个被添加到queue里面的block永远不会被执行