什么是GCD?
全称是Grand Central Dispatch 可译为 “牛逼的中枢调度器”
纯C语言,提供了非常多强大的函数。
GCD的优势
GCD是苹果公司为多核的并行运算提出的解决方案
GCD会自动利用更多的CPU内核(比如双核、四核)
GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理的代码。
注意:一是:更好的利用多核,二是:不用管理线程。
GCD中有2个核心概念?
任务:执行什么操作。
队列:用来存放任务。
GCD使用的2个步骤
定制任务:确定想做的事情。
将任务添加到队列中:GCD会自动将队列中的任务取出,放到对应的线程中执行。
任务的取出遵循队列的FIFO原则:先进先出,后进后出。
涉及的单词:dispatch:派遣,调度。
queue:队列。
sync:同步。
async:异步。
concurrent:并发。
GCD中有2个用来执行任务的函数
用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block)
queue: 队列 block: 任务
用异步的方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block)
同步和异步的区别:
同步:在当前的线程中执行
异步: 载另一条线程中执行
GCD的队列可以分为3大类型:
并发队列(Concurrent Dispatch Queue)
可以让多个任务(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效。
串行队列(Serial Dispatch Queue)
让任务一个接着一个的执行(一个任务执行完毕,再执行下一个任务)
容易混淆的术语:同步、异步、并发、串行
同步和异步决定了要不要开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力。
异步:在新的线程中执行任务,具备开启线程的能力。
并发和串行决定了任务的执行方式
并发:多个任务并发(同时)执行。
串行:一个任务执行完毕后,再执行下一个任务。
串行队列同步执行:不开线程,在原来的线程里一个一个顺序执行。
串行队列异步执行:开一条线程,在这个新的线程里一个一个顺序执行。
并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行。
并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行。
阶段性总结:
1. 开不开线程,由执行任务方法决定,同步不开线程,异步一定开线程。
2. 开多少线程由队列决定,串行最多开一个线程,并发可以开多个线程。具体开多少个由GCD底层决定,程序员无法控制。
具体代码如下所示:
//
// ViewController.m
// GCD的简单使用
//
// Created by apple on 15/10/20.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 核心概念:
// 任务:Block 即将任务保存到一个Block中去。
// 队列: 把任务放到队列里面,队列先进先出的原则,把任务一个个取出(放到对应的线程)执行。
// 串行队列:顺序执行。即一个一个的执行。
// 并行队列:同时执行。同时执行很多个任务。
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self gcdTest2];
}
#pragma mark GCD 演练
/*
串行队列:顺序,一个一个执行。
同步:在当前线程执行,不会开辟新线程。
dispatch:调度,GCD里面的函数都是以dispatch开头的。
*/
-(void)gcdTest1
{
// 1. 创建一个串行队列
// 参数:1.队列标签(纯c语言) 2.队列的属性
dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);
// 2. 同步执行任务
// 一般只要使用“同步” 执行,串行队列对添加的任务,会立马执行。
dispatch_sync(queue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
NSLog(@"完成!");
}
/**
串行队列:任务必须要一个一个先后执行。
异步执行:肯定会开新线程,在新线程执行。
结果:只会开辟一个线程,而且所有任务都在这个新的线程里面执行。
*/
-(void)gcdTest2
{
// 1. 串行队列
dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);
// 按住command进入, #define DISPATCH_QUEUE_SERIAL NULL
// DISPATCH_QUEUE_SERIAL 等于直接写NULL, 且开发的时候都使用NULL
// 2. 异步执行
for (int i=0 ; i<10 ; i++) {
dispatch_async(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
/**
并发队列:可以同时执行多个任务,
异步执行:肯定会开新线程,在新线程执行。
结果:会开很多个线程,同时执行。
*/
-(void)gcdTest3
{
// 1. 并发队列
dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);
// 异步执行任务
for (int i=0 ; i<10 ; i++) {
dispatch_async(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
/**
并发队列:可以同时执行多个任务
同步执行:不会开辟新线程,是在当前线程执行。
结果:不开新线程,顺序执行。
*/
-(void)gcdTest4
{
// 并发队列
dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_CONCURRENT);
for (int i=0 ; i< 10; i++) {
dispatch_sync(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
/**
解析如下:
串行队列:即要求按顺序挨个执行队列内的任务,即一次只执行一个。
并行队列:即要求同时执行队列内的任务。即一次要执行一个或多个队列内的任务。
同步执行:即只在当前线程执行队列内的任务,不会另外开辟新的线程。
异步执行:即开辟一个或多个新的线程来执行队列内的任务,让新的线程来执行。
串行队列同步执行:即由当前线程按顺序执行队列内的任务,不会开辟新的线程。
串行队列异步执行:即另外开辟一个新的线程(仅仅一个),并由这个新的线程来顺序执行队列内的任务,因为异步就是另外开辟线程,又因为串行队列一次只要求执行一个,所以只开辟一个新的线程来顺序执行即可。
并行队列同步执行:即由当前线程同时执行队列内的任务。由于当前单线程是无法实现同时执行多个任务即无法一次执行多个任务,所以只会由当前线程顺序执行队列内的任务。
并行队列异步执行:另外开辟多个线程来同时执行队列内的任务。因为队列内的任务要求同时执行多个,又可以开辟新的线程。所以会开辟多个新的线程来同时执行队列内的任务。但执行任务的顺序不确定,且开辟新线程的个数不确定。
需要注意的是:同步只在当前线程执行。异步只在别的线程执行。
*/
@end
运行结果如下: