博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GCD 并发 VS 串行 同步 VS 异步
阅读量:6092 次
发布时间:2019-06-20

本文共 6104 字,大约阅读时间需要 20 分钟。

并发队列

特点:同时调度多个任务(注意:也是按FIFO调度),不会等待上一个任务完成,再调度下一个。

一、并发队列 异步任务

为每个任务新创建一个线程执行。

dispatch_queue_t concurrentQueue = dispatch_queue_create("com.my.concurrent", DISPATCH_QUEUE_CONCURRENT);    dispatch_async(concurrentQueue, ^{        NSLog(@"并发队列 异步任务0: %@", [NSThread currentThread]);    });    dispatch_async(concurrentQueue, ^{        sleep(4);        NSLog(@"并发队列 异步任务1: %@", [NSThread currentThread]);    });    dispatch_async(concurrentQueue, ^{        sleep(3);        NSLog(@"并发队列 异步任务2: %@", [NSThread currentThread]);    });    dispatch_async(concurrentQueue, ^{        sleep(2);        NSLog(@"并发队列 异步任务3: %@", [NSThread currentThread]);    });    dispatch_async(concurrentQueue, ^{        sleep(1);        NSLog(@"并发队列 异步任务4: %@", [NSThread currentThread]);    });复制代码
--------并发队列 异步任务---------------2018-03-13 10:39:11.282717+0800 GCDDemo[61398:17145606] 并发队列 异步任务0: 
{number = 3, name = (null)}2018-03-13 10:39:12.287176+0800 GCDDemo[61398:17145602] 并发队列 异步任务4:
{number = 4, name = (null)}2018-03-13 10:39:13.287166+0800 GCDDemo[61398:17145605] 并发队列 异步任务3:
{number = 5, name = (null)}2018-03-13 10:39:14.287177+0800 GCDDemo[61398:17145603] 并发队列 异步任务2:
{number = 6, name = (null)}2018-03-13 10:39:15.287222+0800 GCDDemo[61398:17145604] 并发队列 异步任务1:
{number = 7, name = (null)}复制代码

二、并发队列 同步任务

在当前线程顺序执行;

虽然是并发队列,但由于是同步任务,当上一个任务未完成时,会阻塞当前线程,下一个任务也就无法执行。所以也是顺序执行的。

dispatch_queue_t concurrentQueue = dispatch_queue_create("com.my.concurrent", DISPATCH_QUEUE_CONCURRENT);    dispatch_sync(concurrentQueue, ^{        sleep(4);        NSLog(@"并发队列 同步任务1: %@", [NSThread currentThread]);    });    dispatch_sync(concurrentQueue, ^{        sleep(3);        NSLog(@"并发队列 同步任务2: %@", [NSThread currentThread]);    });    dispatch_sync(concurrentQueue, ^{        sleep(2);        NSLog(@"并发队列 同步任务3: %@", [NSThread currentThread]);    });    dispatch_sync(concurrentQueue, ^{        sleep(1);        NSLog(@"并发队列 同步任务4: %@", [NSThread currentThread]);    });复制代码
2018-03-13 10:40:38.029652+0800 GCDDemo[61453:17148595] 并发队列 同步任务1: 
{number = 1, name = main}2018-03-13 10:40:41.030824+0800 GCDDemo[61453:17148595] 并发队列 同步任务2:
{number = 1, name = main}2018-03-13 10:40:43.032137+0800 GCDDemo[61453:17148595] 并发队列 同步任务3:
{number = 1, name = main}2018-03-13 10:40:44.033434+0800 GCDDemo[61453:17148595] 并发队列 同步任务4:
{number = 1, name = main}复制代码

串行队列

特点: 顺序的调度任务,上一个任务执行完毕,才会调度下一个任务。

一、串行队列 异步执行

创建一个新的线程,在新的线程中顺序执行。

虽然是异步任务,但是由于是同步队列,所以会在同一个线程上顺序调度,当前线程完成上一个任务时,才会执行下一个任务。

dispatch_queue_t serialQueue = dispatch_queue_create("com.my.serial", DISPATCH_QUEUE_SERIAL);    dispatch_async(serialQueue, ^{        sleep(4);        NSLog(@"串行队列 异步任务1: %@", [NSThread currentThread]);    });    dispatch_async(serialQueue, ^{        sleep(3);        NSLog(@"串行队列 异步任务2: %@", [NSThread currentThread]);    });    dispatch_async(serialQueue, ^{        sleep(2);        NSLog(@"串行队列 异步任务3: %@", [NSThread currentThread]);    });    dispatch_async(serialQueue, ^{        sleep(1);        NSLog(@"串行队列 异步任务4: %@", [NSThread currentThread]);    });复制代码
2018-03-13 10:54:18.848320+0800 GCDDemo[61918:17171634] 串行队列 异步任务1: 
{number = 3, name = (null)}2018-03-13 10:54:21.853179+0800 GCDDemo[61918:17171634] 串行队列 异步任务2:
{number = 3, name = (null)}2018-03-13 10:54:23.857731+0800 GCDDemo[61918:17171634] 串行队列 异步任务3:
{number = 3, name = (null)}2018-03-13 10:54:24.861741+0800 GCDDemo[61918:17171634] 串行队列 异步任务4:
{number = 3, name = (null)}复制代码

二、串行队列 同步执行

顺序的在当前线程执行。

dispatch_queue_t serialQueue = dispatch_queue_create("com.my.serial", DISPATCH_QUEUE_SERIAL);    dispatch_sync(serialQueue, ^{        sleep(4);        NSLog(@"串行队列 同步任务1: %@", [NSThread currentThread]);    });    dispatch_sync(serialQueue, ^{        sleep(3);        NSLog(@"串行队列 同步任务2: %@", [NSThread currentThread]);    });    dispatch_sync(serialQueue, ^{        sleep(2);        NSLog(@"串行队列 同步任务3: %@", [NSThread currentThread]);    });    dispatch_sync(serialQueue, ^{        sleep(1);        NSLog(@"串行队列 同步任务4: %@", [NSThread currentThread]);    });复制代码
2018-03-13 10:55:29.318125+0800 GCDDemo[61966:17173944] 串行队列 同步任务1: 
{number = 1, name = main}2018-03-13 10:55:32.318892+0800 GCDDemo[61966:17173944] 串行队列 同步任务2:
{number = 1, name = main}2018-03-13 10:55:34.319660+0800 GCDDemo[61966:17173944] 串行队列 同步任务3:
{number = 1, name = main}2018-03-13 10:55:35.320929+0800 GCDDemo[61966:17173944] 串行队列 同步任务4:
{number = 1, name = main}复制代码

主队列(main queue)

特点:

  • 不会开启线程,所有任务都在主线程执行,无论同步还是异步;
  • 上一个任务执行完毕,才会调度下一个任务。(串行队列的性质)

一、主队列 异步任务

在主线程顺序执行。

dispatch_async(dispatch_get_main_queue(), ^{        sleep(4);        NSLog(@"主队列 异步任务1:%@", [NSThread currentThread]);    });    dispatch_async(dispatch_get_main_queue(), ^{        sleep(3);        NSLog(@"主队列 异步任务2:%@", [NSThread currentThread]);    });    dispatch_async(dispatch_get_main_queue(), ^{        sleep(2);        NSLog(@"主队列 异步任务3:%@", [NSThread currentThread]);    });    dispatch_async(dispatch_get_main_queue(), ^{        sleep(1);        NSLog(@"主队列 异步任务4:%@", [NSThread currentThread]);    });复制代码
2018-03-13 10:58:17.316804+0800 GCDDemo[62068:17179639] 主队列 异步任务1:
{number = 1, name = main}2018-03-13 10:58:20.318195+0800 GCDDemo[62068:17179639] 主队列 异步任务2:
{number = 1, name = main}2018-03-13 10:58:22.318997+0800 GCDDemo[62068:17179639] 主队列 异步任务3:
{number = 1, name = main}2018-03-13 10:58:23.320285+0800 GCDDemo[62068:17179639] 主队列 异步任务4:
{number = 1, name = main}复制代码

二、主队列 同步任务

死锁

dispatch_sync会把一个同步任务追加到主队列(main queue)的队尾,同时阻塞当前线程。由于是同步队列,所以只有当该任务之前的所有任务调度执行完成以后,才会调度该任务。但是由于当前线程被阻塞了,之前的任务完成不了,然后也就无法调度当前任务,这就形成了死锁。

也就是说,任务队列等待线程完成任务,线程等待任务队列调度同步任务,相互等待,也就死锁了。

dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"主队列 同步任务1:%@", [NSThread currentThread]);    });复制代码

转载于:https://juejin.im/post/5aa7541a6fb9a028d2079aa2

你可能感兴趣的文章
AIX内存性能优化和监视
查看>>
MYSQL远程登录权限设置 ,可以让Navicat远程连接服务器的数据库
查看>>
我的无线宽带由器 TP-LINK TL-WR841N如何设置限
查看>>
windowns server 2008 r2 AD桌面文件重定向设置
查看>>
根据格式字符串转换数字字符串
查看>>
Navicat for MySQL使用手记(上)--创建数据库和表
查看>>
mac系统上安装多个jdk版本
查看>>
help
查看>>
嵌套DIV的水平居中2
查看>>
VirtualBox 系统盘 虚拟磁盘 变大?
查看>>
ABP官方文档翻译 4.1 应用服务
查看>>
linux上安装mysql及简单的使用
查看>>
js成功页面 3秒自动跳转--代码分享
查看>>
JavaScript 弹窗类的实现
查看>>
java Iterator Iterable Collection AbstractCollection Map关系
查看>>
BigDecimal 使用 静态方法总结
查看>>
[kuangbin带你飞]专题二十一 概率&期望 部分题解
查看>>
Android2.2+opencv3.1配置实现
查看>>
git在push时候出现timeout的解决方法
查看>>
Android Gradle Groovy自动化构建进阶篇
查看>>