多线程:GCD

2020-12-26  本文已影响0人  小小鸟他大爷

多线程:GCD

The main queue(主线程串行队列): 与主线程功能相同,提交至Main queue的任务会在主线程中执行,

1.  Main queue 可以通过dispatch_get_main_queue()来获取。

2.  Global queue(全局并发队列): 全局并发队列由整个进程共享,有高、中(默认)、低、后台四个优先级别。

Global queue 可以通过调用dispatch_get_global_queue函数来获取(可以设置优先级)

3.  Custom queue (自定义队列): 可以为串行,也可以为并发。

Custom queue 可以通过dispatch_queue_create()来获取;

4.  Group queue (队列组):将多线程进行分组,最大的好处是可获知所有线程的完成情况。

Group queue 可以通过调用dispatch_group_create()来获取,通过dispatch_group_notify,可以直接监听组里所有线程完成情况。

Global queue

获取全局并发队列

//程序默认的队列级别,一般不要修改,DISPATCH_QUEUE_PRIORITY_DEFAULT == 0

dispatch_queue_t globalQueue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//HIGH

dispatch_queue_t globalQueue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

//LOW

dispatch_queue_t globalQueue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

//BACKGROUND

dispatch_queue_t globalQueue4 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

全局并发队列由系统默认生成的,所以无法调用dispatch_resume()和dispatch_suspend()来控制执行继续或中断。

Custom queue 

1.自定义串行队列会发生死锁

注意不要嵌套使用同步执行的串行队列任务

dispatch_queue_t serialQueue = dispatch_queue_create("com.dullgrass.serialQueue", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{

  NSLog(@"会执行的代码");

  dispatch_sync(serialQueue, ^{

      NSLog(@"代码不执行");

  });

});

2.自定义并发队列

dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);

NSLog(@"current task");

dispatch_sync(conCurrentQueue, ^{

     NSLog(@"先加入队列");

});

dispatch_sync(conCurrentQueue, ^{

     NSLog(@"次加入队列");

});

NSLog(@"next task");

Group queue

1.使用场景: 同时下载多个图片,所有图片下载完成之后去更新UI(需要回到主线程)或者去处理其他任务(可以是其他线程队列)。

原理:使用函数dispatch_group_create创建dispatch group,然后使用函数dispatch_group_async来将要执行的block任务提交到一个dispatch queue。同时将他们添加到一个组,等要执行的block任务全部执行完成之后,使用dispatch_group_notify函数接收完成时的消息。

dispatch_queue_t conCurrentGlobalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_queue_t mainQueue = dispatch_get_main_queue();

dispatch_group_t groupQueue = dispatch_group_create();

NSLog(@"current task");

dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{

      NSLog(@"并行任务1");

});

dispatch_group_async(groupQueue, conCurrentGlobalQueue, ^{

      NSLog(@"并行任务2");

});

dispatch_group_notify(groupQueue, mainQueue, ^{

      NSLog(@"groupQueue中的任务 都执行完成,回到主线程更新UI");

});

NSLog(@"next task");

2015-11-19 13:47:55.117 Whisper[1645:97116] current task

2015-11-19 13:47:55.117 Whisper[1645:97116] next task

2015-11-19 13:47:55.119 Whisper[1645:97178] 并行任务1

2015-11-19 13:47:55.119 Whisper[1645:97227] 并行任务2

2015-11-19 13:47:55.171 Whisper[1645:97116] groupQueue中的任务 都执行完成,回到主线程更新UI

1.dispatch_after延时添加到队列

dispatch_time_t delayTime3 = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);

dispatch_time_t delayTime2 = dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC);

dispatch_queue_t mainQueue = dispatch_get_main_queue();

NSLog(@"current task");

dispatch_after(delayTime3, mainQueue, ^{

      NSLog(@"3秒之后添加到队列");

});

dispatch_after(delayTime2, mainQueue, ^{

       NSLog(@"2秒之后添加到队列");

});

NSLog(@"next task");

2015-11-19 15:50:19.369 Whisper[2725:172593] current task

2015-11-19 15:50:19.370 Whisper[2725:172593] next task

2015-11-19 15:50:21.369 Whisper[2725:172593] 2秒之后添加到队列

2015-11-19 15:50:22.654 Whisper[2725:172593] 3秒之后添加到队列

dispatch_after只是延时提交block,并不是延时后立即执行,并不能做到精确控制,需要精确控制的朋友慎用哦

dispatch_apply在给定的队列上多次执行某一任务,在主线程直接调用会阻塞主线程去执行block中的任务。

dispatch_apply函数的功能:把一项任务提交到队列中多次执行,队列可以是串行也可以是并行,dispatch_apply不会立刻返回,在执行完block中的任务后才会返回,是同步执行的函数。

dispatch_apply正确使用方法:为了不阻塞主线程,一般把dispatch_apply放在异步队列中调用,然后执行完成后通知主线程

dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);

NSLog(@"current task");

dispatch_async(globalQueue, ^{

   dispatch_queue_t applyQueue= dispatch_get_global_queue(0, 0);

   //第一个参数,3--block执行的次数

   //第二个参数,applyQueue--block任务提交到的队列

   //第三个参数,block--需要重复执行的任务

   dispatch_apply(3, applyQueue, ^(size_t index) {

          NSLog(@"current index %@",@(index));

          sleep(1);

   });

   NSLog(@"dispatch_apply 执行完成");

   dispatch_queue_t mainQueue= dispatch_get_main_queue();

   dispatch_async(mainQueue, ^{

          NSLog(@"回到主线程更新UI");

  });

});

NSLog(@"next task");

2015-11-19 16:24:45.015 Whisper[4034:202269] current task

2015-11-19 16:24:45.016 Whisper[4034:202269] next task

2015-11-19 16:24:45.016 Whisper[4034:202347] current index 0

2015-11-19 16:24:45.016 Whisper[4034:202344] current index 1

2015-11-19 16:24:45.016 Whisper[4034:202345] current index 2

2015-11-19 16:24:46.021 Whisper[4034:202347] dispatch_apply 执行完成

2015-11-19 16:24:46.021 Whisper[4034:202269] 回到主线程更新UI

嵌套使用dispatch_apply会导致死锁

3.dispatch_once保证在app运行期间,block中的代码只执行一次

//GCD实现单例功能

+ (ShareManager *)shareManager

{

  static dispatch_once_t onceToken;

  dispatch_once(&onceToken, ^{

      sharedManager= [[self alloc] init];

  });

  return sharedManager;

 }

//在ARC下,非GCD,实现单例功能

+ (ShareManager *)sharedManager

{

  @synchronized(self) {

      if (!sharedManager) {

          sharedManager= [[self alloc] init];

      }

  }

  return sharedManager;

 }

4.dispatch_barrier_async 栅栏的作用

功能:是在并行队列中,等待在dispatch_barrier_async之前加入的队列全部执行完成之后(这些任务是并发执行的)再执行dispatch_barrier_async中的任务,dispatch_barrier_async中的任务执行完成之后,再去执行在dispatch_barrier_async之后加入到队列中的任务(这些任务是并发执行的)

dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.dullgrass.conCurrentQueue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(conCurrentQueue, ^{

      NSLog(@"dispatch 1");

});

dispatch_async(conCurrentQueue, ^{

       NSLog(@"dispatch 2");

});

dispatch_barrier_async(conCurrentQueue, ^{

       NSLog(@"dispatch barrier");

});

dispatch_async(conCurrentQueue, ^{

       NSLog(@"dispatch 3");

});

dispatch_async(conCurrentQueue, ^{

       NSLog(@"dispatch 4");

});

2015-11-19 18:12:34.125 Whisper[22633:297257] dispatch 1

2015-11-19 18:12:34.125 Whisper[22633:297258] dispatch 2

2015-11-19 18:12:34.126 Whisper[22633:297258] dispatch barrier

2015-11-19 18:12:34.127 Whisper[22633:297258] dispatch 3

2015-11-19 18:12:34.127 Whisper[22633:297257] dispatch 4

上一篇 下一篇

猜你喜欢

热点阅读