代码改变世界

论-多线程之全局队列(并行队列)与主队列(串行队列)

2016-03-21 00:44  菜鸟Alex  阅读(2704)  评论(0编辑  收藏  举报


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self GCDDemo4];

}


//==========================================

//GCD的两个核心,队列和任务
//1.创建队列,(获取队列)
//2.将任务添加到队列中

//根据队列的性质分为并行队列(全局队列),和串行队列(主队列)
//并行和串行只会决定添加到队列中的任务是串行执行还是并行执行!


//根据任务的执行顺序分同步和异步
//同步和异步只会决定要不要等当前定制的任务执行完毕之后在执行之后的代码

//串行队列(主队列),同步执行  ----死锁
//根据同步的特点来看
//先执行任务1,在执行任务2,最后执行任务3
//根据串行队列的特点来看
//先执行任务1,再执行任务3,最后执行任务2

//主队列--必须要主线程中的任务执行完毕,才会执行主队列中的任务
//执行的顺序  任务1 任务3  任务2

//dispatch_sync
//执行顺序  任务1 - 任务2 - 任务3
-(void)GCDDemo1{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"任务1-%@",[NSThread currentThread]);
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"任务2%@",[NSThread currentThread]);
        });
        NSLog(@"任务---3%@",[NSThread currentThread]);
    });
    NSLog(@"任务4--%@",[NSThread currentThread]);
}

dispatch_async(dispatch_get_global_queue(0, 0)任务加到全局队列异步执行,开启子线程,任务4主线程,任务1子线程,这两个执行顺序谁先谁后都有可能(因为是异步执行),4的执行概率高一些.dispatch_sync(dispatch_get_main_queue()任务加到主队列,同步执行,不开启子线程,只能任务2执行完毕再往下执行任务3,任务1与任务4多试几次就知道他俩的执行顺序不固定



//并行队列(全局队列),同步执行
//先执行任务1,在执行任务2,最后执行任务3
//串行队列(主队列),同步执行,没有开启新的线程
-(void)GCDDemo2{
    NSLog(@"任务1-%@",[NSThread currentThread]);
    for (int i = 0; i < 1000; i++) {
        dispatch_sync(dispatch_get_global_queue(0, 0), ^{
//            for (int i = 0; i < 1000; i ++) {
                NSLog(@"任务2%@",[NSThread currentThread]);
//            }
        });
    }
    NSLog(@"任务3--%@",[NSThread currentThread]);
}

  • 主线程任务1先执行,dispatch_sync(dispatch_get_global_queue(0, 0)同步执行不开启新线程代码顺序执行,不论是加入了主队列还是全局队列中,都要顺序执行,所以任务2执行完毕才会轮到任务3


//串行队列(主队列),异步执行
//根据串行队列的特点:
//任务的执行顺序应该是,先执行任务1,在执行任务3,最后执行任务2 ---
//因为是异步,那么任务2有没有可能会在任务3之前执行呢?
//???如果对于队列的执行顺序有疑问的话,我们将任务2添加1000次,最后看看是否任务2可能在任务3的前面
//通过1000次的循环来看,任务2一定在任务3的后面执行
//这个是为什么呢,因为将任务添加到的队列是主队列,主队列是一个串行队列,串行队列的特点是按照顺序执行,所以任务2就一定被添加到任务3的前面!

//串行队列(主队列),异步执行,没有开启新的线程
//主队列--必须要主线程中的任务执行完毕,才会执行主队列中的任务
-(void)GCDDemo3{
    NSLog(@"任务1-%@",[NSThread currentThread]);
//    for (int i = 0; i < 1000; i++) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"任务2--%@",[NSThread currentThread]);
        });
//    }
    NSLog(@"任务3--%@",[NSThread currentThread]);
    
}

  • 任务1主线程,先执行. dispatch_async(dispatch_get_main_queue(),任务2放到主队列;异步执行,由于主队列是串行队列,主队列的任务要等主线程的任务3执行完毕后才可以执行.则执行顺序为132


//并行队列(全局队列),异步执行
//任务的执行顺序是 任务1,任务3和任务2是并发执行的

-(void)GCDDemo4{
    NSLog(@"任务1-%@",[NSThread currentThread]);
    for (int i = 0; i < 1000; i++) {
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"任务2%@",[NSThread currentThread]);
        });
    }

    NSLog(@"任务3%@",[NSThread currentThread]);
    
}

@end


  • 任务1在主线程,先执行,dispatch_async(dispatch_get_global_queue(0, 0)任务2加入并发队列,异步执行,则会开启子线程,则任务3与任务2并发执行.

小结:

  • 主队列的任务要等主线程的任务执行完毕后才可以执行.
  • 不管是在全局队列还是主队列中同步执行则都会按照代码顺序依次上到下执行
  • 在主队列异步执行也是按照代码顺序依次从上到下执行.主队列是串行队列,同步执行依然如此.