ios-GCD的队列介绍

来源:互联网 发布:如何做数据分析研究 编辑:程序博客网 时间:2024/05/21 15:26

GCD有两个用来执行任务的函数,queue是队列的意思,block中写我们要执行的任务

一种是同步的方式去执行任务

 dispatch_sync(dispatch_queue_t  _Nonnull queue, ^{            });

一种是异步的方式去执行任务

  dispatch_async(dispatch_queue_t  _Nonnull queue, ^{            });
GCD中的队列可以分为两大类,一个是并发队列,一个是串行队列

并发队列(Concurrent Dispatch Queue)

可以让多个任务并发的执行,会自动的开启多个线程去”同时“执行任务

并发功能只有在异步(dispatch_async)函数下才有效

串行队列(Serial Dispatch Queue)

让任务一个接着一个地执行就是一个任务执行完毕后,再执行下一个任务。、

总结一下

同步和异步决定了要不要开启新的线程

同步:在当前线程中执行任务,不具备开启新线程的能力

异步:在新的线程中执行任务,具备开启新线程的能力

并发和串行决定了任务的执行方式

并发:多个任务并发的执行

串行:一个任务执行完毕后,再执行下一个任务

串行队列同步执行

 //串行队列,同步执行,不会开启新线程,任务是按顺序来执行的    dispatch_queue_t queue=dispatch_queue_create("hh", DISPATCH_QUEUE_SERIAL);    for(int i=0;i<10;i++)    {        dispatch_sync(queue, ^{            NSLog(@"hello %d %@",i,[NSThread currentThread]);        });    }
串行队列异步执行

//串行队列,异步执行 会开启一个新线程,任务是有序执行的    dispatch_queue_t queue=dispatch_queue_create("hh", DISPATCH_QUEUE_SERIAL);    for(int i=0;i<10;i++)    {        dispatch_async(queue, ^{            NSLog(@"hello %d %@",i,[NSThread currentThread]);        });    }
并行队列同步执行
   //并行队列 同步执行 是和串行队列同步执行效果是一样的,不开线程,顺序执行    dispatch_queue_t queue=  dispatch_queue_create("hh", DISPATCH_QUEUE_CONCURRENT);    for(int i=0;i<10;i++)    {    dispatch_sync(queue, ^{        NSLog(@"%d %@",i,[NSThread currentThread]);    });    }
并行队列异步执行

  //并行队列 异步执行 开启多个线程 无序的去执行   dispatch_queue_t queue=  dispatch_queue_create("hl", DISPATCH_QUEUE_CONCURRENT);    for(int i=0;i<10;i++)    {    dispatch_async(queue, ^{        NSLog(@"%@",[NSThread currentThread]);    });    }

主队列的异步执行

 //主队列 异步执行 就是主线程 顺序的去执行    //主队列的特点就是先执行主线程上的代码,等执行完毕之后,再去执行主队列中的任务    //主队列又叫全局串行队列    for(int i=0;i<10;i++)    {        dispatch_async(dispatch_get_main_queue(), ^{            NSLog(@"%d %@",i,[NSThread currentThread]);        });    }
主队列同步执行

 //主队列 同步执行 同步执行会等着第一个任务执行完成,才会继续往后执行,主队列 同步执行在主线程上执行的话会死锁    //这里会产生一个死锁的情况,主线程正在执行代码等待你同步执行,执行完,而你同步执行在等待你主线程去把第一个任务执行完,再执行下一个任务,相互等待。    for(int i=0;i<10;i++)    {        dispatch_sync(dispatch_get_main_queue(), ^{            NSLog(@"%d %@",i,[NSThread currentThread]);        });    }
解决死锁

//解决死锁,这里是这样的,我们添加任务,同步执行的操作在子线程上完成,然后任务在主线程上去完成,这样主线程就不需要等你同步执行执行完毕,这样就可以避免相互  等待的情况了。也就是说执行dispatch_sync也就是添加任务是在子线程上执行的    dispatch_async(dispatch_get_global_queue(0, 0), ^{        NSLog(@"%@",[NSThread currentThread]);            for(int i=0;i<10;i++)            {                dispatch_sync(dispatch_get_main_queue(), ^{                    NSLog(@"%d %@",i,[NSThread currentThread]);                });            }    });
全局队列本质就是并发队列,全局队列是一直在的,第一个参数就是队列的优先级的概念,如果写0就表示是default,并发队列有名称,可以跟踪错误,全局队列没有名称

 dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)

有一个需要注意的就是如果我们创建了个并发队列,先放一个同步任务到队列中再放两个异步任务到队列中的话,那么就会如果队列先去调度同步任务然后是要等同步任务执行完成之后才会执行下面的异步任务。代码如下所示,会先把所有的kkkk输出完,然后在执行下面的异步任务。

  dispatch_queue_t queue = dispatch_queue_create("哈哈哈",DISPATCH_QUEUE_CONCURRENT);        dispatch_sync(queue, ^{        for(int i=0;i<100;i++)        {        NSLog(@"kkkkk");        }    });    dispatch_async(queue, ^{        NSLog(@"dandjan");    });    dispatch_async(queue, ^{        NSLog(@"dadasw");    });