标签:
当想要任务按照某一个特定的顺序执行时,串行队列是很有用的。串行队列在同一个时间只执行一个任务。我们可以使用串行队列代替锁去保护共享的数据。和锁不同,一个串行队列可以保证任务在一个可预知的顺序下执行。
//创建串行的队列
//第一个参数表示queue的名字,,,第二个参数表示queue的类型
dispatch_queue_t queue_1 = dispatch_queue_create("queue.1", DISPATCH_QUEUE_SERIAL); |
//创建并行的队列
dispatch_queue_t queue_2 = dispatch_queue_create("queue.2", DISPATCH_QUEUE_CONCURRENT);
|
//获取全局并发的queue(属于并行队列)
//第一个参数表示优先级,,,第二个参数暂时没用 dispatch_queue_t global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
//获取管理主线程的queue(属于串行队列)
//提交给main queue的任务可能不会立马被执行,而是在主线程的Run Loop检测到有dispatch 提交过来的任务时才会执行
dispatch_queue_t main_queue = dispatch_get_main_queue();
|
//获取全局并发的queue
dispatch_queue_t global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //1.同步提交
//如果使用同步请求方式,会造成卡死当前线程的后果。
//同步提交任务后,先执行完block,然后dispatch_sync()返回 dispatch_sync(global_queue, ^{ NSLog(@"do something"); }); NSLog(@"OK"); |
//2.异步提交
//异步提交任务后,dispatch_async()函数直接返回,无需等待block执行结束。
dispatch_async(global_queue, ^{ NSLog(@"do something....."); }); NSLog(@"OK.....");
|
//3.同步提交多次任务
dispatch_queue_t queue_1 = dispatch_queue_create("queue.1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue_2 = dispatch_queue_create("queue.2", DISPATCH_QUEUE_CONCURRENT);
//任务数量 size_t count = 10; //同步提交多次任务 //三个参数分别是:任务数,目标queue,任务描述 //如果目标queue是串行的,那么任务会依次执行,如果queue是并行的,那么任务会并发的执行,打印的顺序就会被打乱 dispatch_apply(count, queue_2, ^(size_t i) { NSLog(@"%zu",i); }); NSLog(@"---OK---"); //比较同步提交多个任务和遍历数组哪个快 (在不关心数组顺序的前提下)
//遍历数组
NSMutableArray* array = [[NSMutableArray alloc]initWithCapacity:1000]; for (int i =0; i<1000; i++) { [array addObject:[NSString stringWithFormat:@"%d",i]]; } NSLog(@"start forin");
//数组遍历
for (NSString* a in array) {
NSLog(@"--%@",a); } NSLog(@"fisined forin");
NSLog(@"start apply");
//同步提交多个任务
dispatch_apply(array.count, queue_2, ^(size_t i) {
NSLog(@"%@",array[i]); }); NSLog(@"fisined apply");
|
//主线程(属于串行队列)死锁
//不会打印出任何东西
dispatch_queue_t main_queue = dispatch_get_main_queue();
//同步执行
dispatch_sync(main_queue, ^{
NSLog(@"-----"); }); NSLog(@"OK");
程序默认是从上往下执行的,但是程序走到dispatch_sync时,又会先走block再返回到dispatch_sync,这样就会照成冲突,形成死锁
|
//串行队列
dispatch_queue_t queue_1 = dispatch_queue_create("queue.1", DISPATCH_QUEUE_SERIAL); //异步提交 dispatch_async(queue_1, ^{ //不会被打印 //同步提交 dispatch_sync(queue_1, ^{ NSLog(@"bbb"); }); NSLog(@"ccccc"); }); NSLog(@"aaaa");
|
死锁解决方案:串行队列异步执行,并行队列同步执行。
串行队列中 ,同步提交任务给本身队列,就会出现死锁。要想不出现死锁就把串行队列改为并行队列,或把同步提交任务改为异步提交。
|
//1.创建group
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
|
//2.提交一个任务给global_queue ,并且添加到group中
/ / global_queue并非是一个queue,但group必须是同一个
/ / group只有异步提交,没有同步提交
dispatch_group_async(group, global_queue, ^{
usleep(10000); NSLog(@"买锅"); }); dispatch_group_async(group, global_queue, ^{ usleep(10000); NSLog(@"买菜"); }); dispatch_group_async(group, global_queue, ^{ usleep(10000); NSLog(@"买饮料"); });
|
//3.异步提交终极任务给queue ,main_queue
//终极任务就相当于operation1依赖于Operation2一样,只是operation1不能和之前提交任务一样,而是需要终极任务dispatch_group_notify提交
//异步提交 不阻塞当前线程
//要想阻塞当前线程,一直等待group所有任务结束,需要用到dispatch_group_wait
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"吃火锅"); }); |
//创建dispatch time
//可以自定义超时时间,只等待一定的时间
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(200 * NSEC_PER_SEC));
//4.自定义超时时间
//设置超时时间,阻塞当前线程
dispatch_group_wait(group, time);
//买饮料的时间过长,已经超过了等待的时间,所以很难再执行
NSLog(@"....");
NSLog(@"看电视");
|
标签:
原文地址:http://www.cnblogs.com/gaominmin/p/4821527.html