1、什么是GCD?
GCD全称 Grand Central Dispatch,纯C语言API,提供非常强大的函数。
2、核心:任务和队列
将任务添加到队列,并且指定执行任务的函数。
任务:需要执行的操作。
队列:指执行任务的等待队列。是一种线性表,先进先出(FIFO)原则。
// 任务
dispatch_block_t block = ^{
NSLog(@"Hello");
};
// 队列
dispatch_queue_t queue = dispatch_queue_create("cwwng-queue", NULL);
// 函数
dispatch_async(queue, block);
同步与异步:
同步(dispatch_sync):必须等待当前语句执行完毕,才会执行下一条语句。不会开启线程,在当前线程执行block任务。
异步(dispatch_async):不用等待当前语句执行完毕,可执行下一条语句。会开启线程执行block任务。
注意:异步执行(async)具有开启新线程的能力,但是并不一定开启新线程,这跟任务所指定的队列类型有关。
串行队列与并发队列:
串行队列(Serial Dispatch Queue):每次只有一个任务被执行,任务按顺序一个接一个地执行。(只开启一个线程)
并发队列(Concurrent Dispatch Queue):可以让多个任务并发执行。(开启多个线程)
3、队列的类型
全局队列:是并发队列。
主队列:是一种特殊的串行队列。
// 串行队列创建
dispatch_queue_t queueSeial = dispatch_queue_create("com.seial", DISPATCH_QUEUE_SERIAL);
// 并发队列创建
dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
// 主队类获取
dispatch_queue_t queueMain = dispatch_get_main_queue();
// 全局队类获取
dispatch_queue_t queueGlobal = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
4、任务的创建
// 同步任务
dispatch_sync(queueMain, ^{
// 执行同步任务代码
});
// 异步任务
dispatch_async(queueMain, ^{
// 执行异步任务代码
});
5、组合方式
串行队列+同步:不会开启新线程、任务逐步执行。
并发队列+同步:不会开启新线程、任务逐步执行。
主队列+同步:主线程调用,死锁。其他线程调用,不开启线程,逐步执行。
串行队列+异步:会开启一个新线程、任务逐步执行。
并发队列+异步:会开启多个新线程、多任务并发执行。
主队列+异步:不会开启新线程,任务逐步执行。
6、验证5代码
6.1、串行队列+同步
// 不会开启新线程,在当前线程执行任务。任务是串行执行。
dispatch_queue_t queueSeial = dispatch_queue_create("com.seial", DISPATCH_QUEUE_SERIAL);
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 串行队列 + 同步任务
dispatch_sync(queueSeial, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queueSeial, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queueSeial, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_sync(queueSeial, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 17:17:06.200720+0800 Demo[19868:2048817] currentThread - <NSThread: 0x6000003702c0>{number = 1, name = main}
2020-11-06 17:17:10.201407+0800 Demo[19868:2048817] 1 - <NSThread: 0x6000003702c0>{number = 1, name = main}
2020-11-06 17:17:13.202940+0800 Demo[19868:2048817] 2 - <NSThread: 0x6000003702c0>{number = 1, name = main}
2020-11-06 17:17:15.204560+0800 Demo[19868:2048817] 3 - <NSThread: 0x6000003702c0>{number = 1, name = main}
2020-11-06 17:17:16.205038+0800 Demo[19868:2048817] 4 - <NSThread: 0x6000003702c0>{number = 1, name = main}
6.2、并发队列+同步
//不会开启新线程,在当前线程中执行任务。任务是串行执行。
dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 并发队列 + 同步任务
dispatch_sync(queueConcurrent, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queueConcurrent, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queueConcurrent, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_sync(queueConcurrent, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 17:20:44.991766+0800 Demo[20023:2053209] currentThread - <NSThread: 0x60000207c1c0>{number = 1, name = main}
2020-11-06 17:20:48.993349+0800 Demo[20023:2053209] 1 - <NSThread: 0x60000207c1c0>{number = 1, name = main}
2020-11-06 17:20:51.995015+0800 Demo[20023:2053209] 2 - <NSThread: 0x60000207c1c0>{number = 1, name = main}
2020-11-06 17:20:53.996528+0800 Demo[20023:2053209] 3 - <NSThread: 0x60000207c1c0>{number = 1, name = main}
2020-11-06 17:20:54.998143+0800 Demo[20023:2053209] 4 - <NSThread: 0x60000207c1c0>{number = 1, name = main}
6.3、主队列+同步
6.3.1、主线程调用,死锁。
dispatch_queue_t queueMain = dispatch_get_main_queue();
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 主队列 + 同步任务 + 主线程调用
dispatch_sync(queueMain, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 17:27:08.463180+0800 Demo[20300:2060486] currentThread - <NSThread: 0x600002ac4100>{number = 1, name = main}
6.3.2、其他线程调动
// 不会开启新线程,在主线程中执行任务。任务是串行执行。
// 全局队类获取
dispatch_queue_t queueGlobal = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queueGlobal, ^{
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
dispatch_queue_t queueMain = dispatch_get_main_queue();
// 主队列 + 同步任务 + 其他线程线程调用
dispatch_sync(queueMain, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_sync(queueMain, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
});
2020-11-06 17:32:55.484067+0800 Demo[20583:2068194] currentThread - <NSThread: 0x6000007c1040>{number = 4, name = (null)}
2020-11-06 17:32:59.497909+0800 Demo[20583:2068085] 1 - <NSThread: 0x60000078c040>{number = 1, name = main}
2020-11-06 17:33:02.500238+0800 Demo[20583:2068085] 2 - <NSThread: 0x60000078c040>{number = 1, name = main}
2020-11-06 17:33:04.500890+0800 Demo[20583:2068085] 3 - <NSThread: 0x60000078c040>{number = 1, name = main}
2020-11-06 17:33:05.502132+0800 Demo[20583:2068085] 4 - <NSThread: 0x60000078c040>{number = 1, name = main}
6.4、串行队列+异步
// 会开启一个新线程。任务是串行执行。
dispatch_queue_t queueSeial = dispatch_queue_create("com.seial", DISPATCH_QUEUE_SERIAL);
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 异步任务
dispatch_async(queueSeial, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queueSeial, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queueSeial, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_async(queueSeial, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 18:19:31.378634+0800 Demo[20921:2077149] currentThread - <NSThread: 0x60000364c880>{number = 1, name = main}
2020-11-06 18:19:35.383806+0800 Demo[20921:2077231] 1 - <NSThread: 0x600003604100>{number = 4, name = (null)}
2020-11-06 18:19:38.384416+0800 Demo[20921:2077231] 2 - <NSThread: 0x600003604100>{number = 4, name = (null)}
2020-11-06 18:19:40.390142+0800 Demo[20921:2077231] 3 - <NSThread: 0x600003604100>{number = 4, name = (null)}
2020-11-06 18:19:41.393428+0800 Demo[20921:2077231] 4 - <NSThread: 0x600003604100>{number = 4, name = (null)}
6.5、并发队列+异步
// 可开启多个线程。多任务并发执行。
dispatch_queue_t queueConcurrent = dispatch_queue_create("com.concurrent", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 异步任务
dispatch_async(queueConcurrent, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queueConcurrent, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queueConcurrent, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_async(queueConcurrent, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 18:22:07.333160+0800 Demo[21040:2079918] currentThread - <NSThread: 0x600003160980>{number = 1, name = main}
2020-11-06 18:22:08.337539+0800 Demo[21040:2080046] 4 - <NSThread: 0x60000312fb00>{number = 7, name = (null)}
2020-11-06 18:22:09.336083+0800 Demo[21040:2080047] 3 - <NSThread: 0x600003121580>{number = 3, name = (null)}
2020-11-06 18:22:10.338269+0800 Demo[21040:2080049] 2 - <NSThread: 0x600003157240>{number = 8, name = (null)}
2020-11-06 18:22:11.338086+0800 Demo[21040:2080048] 1 - <NSThread: 0x600003128900>{number = 5, name = (null)}
6.6、主队列+异步
// 不会开启新线程,在主线程中执行任务。任务是串行执行。
dispatch_queue_t queueMian = dispatch_get_main_queue();
NSLog(@"currentThread - %@",[NSThread currentThread]); // 打印当前线程
// 异步任务
dispatch_async(queueMian, ^{
sleep(4);
NSLog(@"1 - %@",[NSThread currentThread]);
});
dispatch_async(queueMian, ^{
sleep(3);
NSLog(@"2 - %@",[NSThread currentThread]);
});
dispatch_async(queueMian, ^{
sleep(2);
NSLog(@"3 - %@",[NSThread currentThread]);
});
dispatch_async(queueMian, ^{
sleep(1);
NSLog(@"4 - %@",[NSThread currentThread]);
});
2020-11-06 18:24:40.706290+0800 Demo[21155:2082720] currentThread - <NSThread: 0x60000130c340>{number = 1, name = main}
2020-11-06 18:24:44.811041+0800 Demo[21155:2082720] 1 - <NSThread: 0x60000130c340>{number = 1, name = main}
2020-11-06 18:24:47.812006+0800 Demo[21155:2082720] 2 - <NSThread: 0x60000130c340>{number = 1, name = main}
2020-11-06 18:24:49.813334+0800 Demo[21155:2082720] 3 - <NSThread: 0x60000130c340>{number = 1, name = main}
2020-11-06 18:24:50.813910+0800 Demo[21155:2082720] 4 - <NSThread: 0x60000130c340>{number = 1, name = main}
网友评论