GCD
2016-06-24 本文已影响15人
我爱吃豆芽
1.GCD是最简单的一种多线程,同时也是效率最高的一种方式(全部是用C语言代码编写的API),也是苹果过公司主推的一种多线程方式
2.GCD通过queue来实现多线程
3.GCD里面有多种queue一种是串行serial一种是并行concurrent
pragma mark-------------serial串行队列第一种------------------------
//serial:第一个任务执行完毕,第二个任务才开始执行,依次类推
//有两种方式
//获取主线程
// dispatch_queue_t queue = dispatch_get_main_queue();
//往队列里面添加任务
// dispatch_async(queue, ^{
// NSLog(@"这是第一个任务,当前线程%@,是否主线%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
// });
//
//
// dispatch_async(queue, ^{
// NSLog(@"这是第二个任务,当前线程%@,是否主线程 %d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
//
//
// dispatch_async(queue, ^{
// NSLog(@"这是第三个任务当前线程%@ ,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
//
// dispatch_async(queue, ^{
// NSLog(@"这是第四个第四个任务但钱线程%@,是否主线程 %d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
pragma mark -------------serial串行队列第二种-----------
/*
*获取串行队列的第二种方式,自己创建队列。
*穿件串行队列的第二种方式
“serialQueue” 对列的名字 (苹果主推使用反向域名法去命名)
DISPATCH_QUEUE_SERIAL 队列类型
手动创建的串行队列不在主线程中
*/
//dispatch_sync 是主线程 dispatch_async不是主线程
dispatch_queue_t queue = dispatch_queue_create("com.serialQueue.www", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"这是一个任务,当前 线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"这是第二个任务,但钱线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"这是3%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"只是第四个%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"这是5个任务,当前 线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"这是第6个任务,但钱线程%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"这是7%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"只是第8个%@,是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
concurrentQueue 特点:第一个任务执行开始之后,第二个任务不等第一个执行完毕直接开始执行,以此类推,后边的任务跟前面的任务没有关系(先添加的任务不一定先执行,最后添加的任务不一定最后执行),并列队列会根据队列里面的任务数量、cpu、使用情况开辟最合适的线程数量去完成队列里面的任务 创建有两种方式
pragma mark ------concurrentQueue第一种创建方式-------------
// 创建并行队列
//global queue 是苹果里面的全局队列,有4个优先级
// #define DISPATCH_QUEUE_PRIORITY_HIGH 2
// #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
// #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
// #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
//第一个参数就是队列的优先级 第二个参数就是苹果预留的参数为了以后使用,目前还没有使
// dispatch_queue_t queue = dispatch_queue_create("com.concurrent.www", DISPATCH_QUEUE_CONCURRENT);
//
// dispatch_async(queue, ^{
// NSLog(@"1%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
//
// dispatch_async(queue, ^{
// NSLog(@"2%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
// });
//
// dispatch_async(queue, ^{
// NSLog(@"3%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
// });
//
// dispatch_async(queue, ^{
// NSLog(@"4%@ 是否主%d",[NSThread currentThread] ,[[NSThread currentThread] isMainThread]);
// });
pragma mark ------concurrentQueue第二种创建方式-------------
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSLog(@"线程1%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"线程2%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"线程3%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"线程4%@ 是否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"线程5%@ 谁否主%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
延迟执行代码 (dispatch——after 可以再任何队列中执行,串行并行都可以)
//第一种
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// NSLog(@"我是延迟执行的代码 线程:%@ 是否是主线程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
// });
//第二种
dispatch_time_t seconds = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
//创建一个全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_after(seconds, queue,^{
NSLog(@"我是延迟执行的代码%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread ]);
});
线程组
//dispatch—Group-t主要是一些不想管的任务归为一组
//组里面放到是队列
//dispatch-group-async 作用是给组里面的队列添加任务
//dispatch-group-notify 作用是坚挺组里面的任务,等到组里面的任务全部执行完成之后,才执行它里面的任务
//第一步创建组
dispatch_group_t group = dispatch_group_create();
//创建全局对列
dispatch_queue_t queue = dispatch_queue_create(0, 0);
//往组里面的队列添加任务
dispatch_group_async(group, queue, ^{
NSLog(@"我是第一个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_group_notify(group, queue, ^{
NSLog(@"我是最后一个任务,当其他任务完成之后,我再执行 线程%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是第三个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是第四个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是第五个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_group_async(hroup, queue, ^{
NSLog(@"我是第五个%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
既有数据的写入,也有数据的读取。如何解决该类问题dispatch_barrier_async在它之前的任务可以去并发执行,在它之后的任务也可以并发执行
dispatch_queue_t queue = dispatch_queue_create("com.currentQueue.www", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"第一个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread]isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第二个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第三个任务%@ 是否主线成%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第四个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第5个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_barrier_async(queue, ^{
NSLog(@"我正在读取数据,不要来打扰我%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第6个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
dispatch_async(queue, ^{
NSLog(@"第7个任务%@ 是否主线程%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]);
});
多次执行
NSArray *array = @[@"1",@"2",@"3"];
dispatch_queue_t queue = dispatch_queue_create(0, 0);
/***
*多次执行
*
*@param iterations 次数
*@param queue 队列
*
*@param size_t 任务
*
*
***/
//index 是随机的 是小于次数的随机数
dispatch_apply(3, queue, ^(size_t index) {
NSLog(@"%@",array[index]);
});
async 与 sync的区别
//async 不等block执行完毕,就去执行下面的代码
//sync 会等block执行完毕只后,才会去执行下面的代码
dispatch_queue_t queue = dispatch_queue_create(0, 0);
dispatch_sync(queue, ^{
NSLog(@"这是第一个任务");
});
NSLog(@"呵呵");
dispatch_sync(queue, ^{
NSLog(@"这是第二个任务");
});
NSLog(@"哦");
GCD调用函数指针
- (IBAction)functionPointer:(UIButton *)sender {
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
/***
*GCD 函数做参数
*queue 队列
*contex 函数参数的内容
*work 函数(函数肚饿返回值必须为void 参数类型必须为 void *)
***/
dispatch_async_f(queue, @"呵呵", function);
}
void function(void *context){
NSLog(@"%@",context);
printf("哦");
}
线程互斥
线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的
// 1 创建线程锁
NSLock *lock = [[NSLock alloc]init];
_count = 100;//票数
//创建线程并行队列
dispatch_queue_t queue = dispatch_queue_create("com.sellTicketss.www", DISPATCH_QUEUE_CONCURRENT);
__weak ViewController *weakSelf = self;
for (int i =10; i>0; i--) {
dispatch_async(queue, ^{
[lock lock];
for (int j = 10; j > 0; j--) {
NSLog(@"买到了第%d张票",weakSelf.count);
weakSelf.count -- ;
}
[lock unlock];
});
}