Grand Central Dispatch简称(GCD)是苹果公司开发的技术。 GCD数据函数级的多线程,性能更高,功能也更加强大。
GCD核心概念:具有一定功能的代码段。一般是一个block或者函数。
分发队列:GCD以队列的方式进行工作,FIFO:first in first out。 GCD会根据分发队列的类型创建合适数量的线程执行队列中的任务。
dispatch queue分为两种:
SerialQueue:一次只执行一个任务。Serial(连续的) queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue是,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。SerialQueue能实现线程同步。 Concurrent:可以并发地执行多个任务,但是遵守FIFO。
GCD方法:
dispatch_async() //向队列中添加任务,任务会排队执行
dispatch_after() //向队列中添加任务,任务不但会排队,还会过一段时间以后
在执行,这个时间自己设定。
dispatch_apply() //向队列中添加任务,任务会重复执行n次--次数自己设定;
dispatch_group_async() //将任务添加到队列中,并添加分组标记
dispatch_group_notify() //将任务添加到队列中,当某个分组的所有任务都执行
完成后,此任务才会执行。
dispatch_barrier_async() //将任务添加到队列中,此任务执行的时候,其他任务停止执行。
dispatch_once() //任务添加到队列中,但恩物在程序执行的过程中,只执行一次。
dispatch_sync() //将任务添加到队列中,block不执行完,下面代码不会执行。
dispatch_async_f() //将任务添加到队列中,任务是函数非block。
注:gcd不支持结束子线程操作
线程间通信分为两种:
主线程进入子线程(前面的方法都是)。 子线程回到主线程方法有两种:
GCD:dispatch_get_main_queue()
NSObject:- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
线程互斥
线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它型。 互斥无法限制访问者对资源的访问顺序,即访问是无序的,因此需要加上互斥锁来进行顺序访问, 最具有代表性的就是买票系统! NSLock类能协助完成互斥操作。 多线程间相互通讯
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//子线程完成操作
UIImage *image = nil;
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程
});
/**
//直接将得到的数据传到下面的方法中,在主线程中对得到对象进行处理
[self performSelectorOnMainThread:@selector(heheh:) withObject:image waitUntilDone:NO];
[self performSelector:@selector(heheh:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES modes:nil];
*/
});
// GCD:Grand Central Dispatch
/*
同步线程也并发线程都各自包括两种,一种是系统提供的线程,另外一种 就是自己创造的线程
*/
// 4.1同步线程
// 4.1.1获取同步队列 获取系统提供的主队列
/*
系统给每个应用程序提供了三个concurrent dispatch queue。
这三个并发调度队列是全局的,它们只有优先级的不同。
因为是全局的,我们不需要去创建。我们只需要通过使用该函数
dispath_get_global_queue去得到队列
系统默认就有一个串行队列main_queue
dispatch_queue_t global = dispatch_get_global_queue
(DISPATCH_QUEUE_PREIORITY_DEFAULT,0);
dispatch_queue_t main = dispatch_get_main_queue();
*/
// dispatch_queue_t queue = dispatch_get_main_queue();
//// dispatch_async是在另外一个线程中处理这些操作,然后再通知
//// 主线程更新界面
// dispatch_async(queue, ^{
// NSLog(@"%@--%d",[NSThread currentThread],[NSThread isMainThread]);
// });
// 4.1.2 创建自定义同步队列
dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.150303", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"%@---%d",[NSThread currentThread],[NSThread isMainThread]);
});
// 4.2 并发队列
// 4.2.1 获取系统提供的并发队列,所有的线程同时运行
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 100; i ++) {
NSLog(@"1");
sleep(1);
}
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 100; i ++) {
NSLog(@"2");
sleep(1);
}
});
// 4.2.2 创建自定义并发队列
dispatch_async(dispatch_queue_create("com.lanou3g.150303.concurrent", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"hahah");
});
// dispatch_after的使用
// 方法在time时间过去之后开始执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"hahaha");
});
// dispatch_apply重复执行
// 第一个参数表示重复执行任务次数
// Parameter name omitted 参数名字缺失,添加block参数
dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) {
NSLog(@"hahah");
});
// dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他他的操作
dispatch_group_async(dispatch_group_create(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"hahha");
});
dispatch_group_async(dispatch_group_create(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"heheh");
});
dispatch_group_async(dispatch_group_create(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"heihei");
});
// 上边的任务都完成了再执行这个通知任务
dispatch_group_notify(dispatch_group_create(), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"oheheeh");
});
// dispatch_barrier_async的使用
dispatch_async(dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"hahahh");
});
dispatch_async(dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"hahahh");
});
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"hljljl");
});
dispatch_async(dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"hahahh");
});
// dispatch_once只执行一次
// dispatch_sync是同步分发,这个任务没有完成下边的语句不执行
// dispatch_async是异步分发,任务没哟完成就克执行下边的语句
// 后边加_f的是函数形式
dispatch_async_f(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), "hehe", func);