ios - 多线程之七:GCD并行

接以上项目,我们开始 GCD 并行队列的使用

创建按钮入口

UIButton *btn4 = [UIButton buttonWithType:UIButtonTypeCustom];
btn4.frame = CGRectMake(40, 300, 100, 40);
[btn4 setTitle:@"GCD并行" forState:UIControlStateNormal];
[btn4 setBackgroundColor:[UIColor blueColor]];
[btn4 addTarget:self action:@selector(click_GCD_Parallel) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn4];

dispatch_get_global_queue

情况一:同步任务 + 全局队列

可以在任务创建时,设置在队列中的优先级

 /*
    //GCD - 并行队列中任务的执行优先级
 *  - DISPATCH_QUEUE_PRIORITY_HIGH:         QOS_CLASS_USER_INITIATED
 *  - DISPATCH_QUEUE_PRIORITY_DEFAULT:      QOS_CLASS_DEFAULT
 *  - DISPATCH_QUEUE_PRIORITY_LOW:          QOS_CLASS_UTILITY
 *  - DISPATCH_QUEUE_PRIORITY_BACKGROUND:   QOS_CLASS_BACKGROUND
 */

dispatch_sync(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"开始子线程 :task1");
    for (int i = 10; i <= 20 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 20) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task1");
            });
        }
    }
});
dispatch_sync(dispatch_get_global_queue(-2, 0), ^{
    NSLog(@"开始子线程 :task2");
    for (int i = 20; i <= 30 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 30) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task2");
            });
        }
    }
});
dispatch_sync(dispatch_get_global_queue(2, 0), ^{
    NSLog(@"开始子线程 :task3");
    for (int i = 30; i <= 40 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 40) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task3");
            });
        }
    }
}); 

执行结果:

ios - 多线程之七:GCD并行_第1张图片
全局 + 同步

日志分析:
1:堵塞主线程;
2:系统不会开启子线程;
3:所有的任务还是在主线程执行;
4:所有同步任务依次按照顺序执行;
5:此时全局队列的优先级起不到作用,任务依旧按照顺序执行;

情况二 : 异步任务 + �全局队列

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"开始子线程 :task4");
    for (int i = 10; i <= 20 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 20) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task1");
            });
        }
    }
});
dispatch_async(dispatch_get_global_queue(-2, 0), ^{
    NSLog(@"开始子线程 :task5");
    for (int i = 20; i <= 30 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 30) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task2");
            });
        }
    }
});
dispatch_async(dispatch_get_global_queue(2, 0), ^{
    NSLog(@"开始子线程 :task6");
    for (int i = 30; i <= 40 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 40) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task3");
            });
        }
    }
});

执行结果:

ios - 多线程之七:GCD并行_第2张图片
全局 + 异步

日志分析:
1:不会堵塞主线程
2:会为每一个异步任务开启一个子线程;
3:可以通过设置任务优先级控制任务的执行优先顺序
4:充分证明全局队列是并行队列

自创建并行队列

情况一:并行队列 + 同步任务
创建并行队列语句

 dispatch_queue_t queue_concurrent = dispatch_queue_create("queue.concurrent", DISPATCH_QUEUE_CONCURRENT);

代码:

dispatch_sync(queue_concurrent, ^{
    NSLog(@"开始子线程 :task7");
    for (int i = 70; i <= 80 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 80) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task7");
            });
        }
    }
});

dispatch_sync(queue_concurrent, ^{
    NSLog(@"开始子线程 :task8");
    for (int i = 80; i <= 90 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 90) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task8");
            });
        }
    }
});

dispatch_sync(queue_concurrent, ^{
    NSLog(@"开始子线程 :task9");
    for (int i = 90; i <= 100 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 100) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task9");
            });
        }
    }
});

执行结果:

ios - 多线程之七:GCD并行_第3张图片
全局 + 同步

日志分析:
1:堵塞主线程
2:任务不会被开启子线程;
3:所有同步任务在主线程中执行;
4:同步任务按照顺序依次执行;

情况二:并行队列 + 异步任务

 dispatch_queue_t queue_concurrent = dispatch_queue_create("queue.concurrent", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue_concurrent, ^{
    NSLog(@"开始子线程 :task7");
    for (int i = 70; i <= 80 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 80) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task7");
            });
        }
    }
});

dispatch_async(queue_concurrent, ^{
    NSLog(@"开始子线程 :task8");
    for (int i = 80; i <= 90 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 90) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task8");
            });
        }
    }
});

dispatch_async(queue_concurrent, ^{
    NSLog(@"开始子线程 :task9");
    for (int i = 90; i <= 100 ; i ++) {
        sleep(1);
        NSLog(@"当前线程名称:%@ ——%d",[NSThread currentThread].name,i);
        if (i == 100) {
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"回到主线程,task9");
            });
        }
    }
});

执行结果:

ios - 多线程之七:GCD并行_第4张图片
并发队列 + 异步任务

日志分析:
1:不会堵塞线程
2:系统会为每一个异步任务开始一个子线程;
3:每个异步任务在自己对应的线程中执行;
4:各个任务之间是并发执行的;

你可能感兴趣的:(ios - 多线程之七:GCD并行)