gcd中有哪些队列?分别是并行还http是串行还是并行

【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例 - 推酷
【iOS开发-91】GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例
(1)GCD实现的同步异步、串行并行。
——同步sync应用场景:用户登录,利用阻塞
——串行异步应用场景:下载等耗时间的任务
因为是异步,所以开通了子线程,但是因为是串行队列,所以只需要开通1个子线程(2),它们在子线程中顺序执行。最常用。
-(void)gcdDemo1{
dispatch_queue_t q1=dispatch_queue_create(&com.hellocation.gcdDemo&, DISPATCH_QUEUE_SERIAL);
for (int i=0; i&10; i++) {
dispatch_async(q1, ^{
NSLog(@&%@&,[NSThread currentThread]);
因为是异步,所以开通了子线程,且因为是并行队列,所以开通了好多个子线程,具体几个,无人知晓,看运气。线程数量无法控制,且浪费。
-(void)gcdDemo2{
dispatch_queue_t q2=dispatch_queue_create(&com.hellocation.gcdDemo&, DISPATCH_QUEUE_CONCURRENT);
for (int i=0; i&10; i++) {
dispatch_async(q2, ^{
NSLog(@&%@&,[NSThread currentThread]);
因为是同步,所以无论是并行队列还是串行队列,都是在主线程中执行
-(void)gcdDemo3{
dispatch_queue_t q1=dispatch_queue_create(&com.hellocation.gcdDemo&, DISPATCH_QUEUE_SERIAL);
for (int i=0; i&10; i++) {
dispatch_sync(q1, ^{
NSLog(@&%@&,[NSThread currentThread]);
全局队列和并行队列类似(全局队列不需要创建直接get即可,而导致其没有名字,不利于后续调试)
-(void)gcdDemo5{
dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i=0; i&10; i++) {
dispatch_sync(q, ^{
NSLog(@&%@&,[NSThread currentThread]);
for (int i=0; i&10; i++) {
dispatch_async(q, ^{
NSLog(@&%@&,[NSThread currentThread]);
因为是主线程,所以异步任务也会在主线程上运行(1)。而如果是同步任务,则阻塞了,因为主线程一直会在运行,所以后米的任务永远不会被执行。
主要用处,是更新UI,更新UI一律在主线程上实现
-(void)gcdDemo6{
dispatch_queue_t q=dispatch_get_main_queue();
for (int i=0; i&10; i++) {
dispatch_sync(q, ^{
NSLog(@&%@&,[NSThread currentThread]);
// for (int i=0; i&10; i++) {
dispatch_async(q, ^{
NSLog(@&%@&,[NSThread currentThread]);
(2)NSOperation和NSOperationQueue实现的线程管理
1、只要是自己创建的队列,添加进来的操作(此处是block操作),都在子线程上(2)
2、只要是在主队列中,添加进来的操作,都在主线程上(1)
两个队列不能同时抢一个任务操作
-(void)opDemo1{
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@&%@&,[NSThread currentThread]);
[queue addOperation:b];
[[NSOperationQueue mainQueue]addOperation:b];
-(void)opDemo2{
NSInvocationOperation *i=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(helloWorld) object:nil];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
[queue addOperation:i];
[[NSOperationQueue mainQueue]addOperation:i];
-(void)helloWorld{
NSLog(@&hello,world!&);
依赖关系:(1)可以保证执行顺序,也使得开的子线程不会太多;(2)可以跨队列,而串行是不可以跨队列的,如最后更新UI则变成在主队列中。
这是NSOperation(NSBlockOperation和NSInvocationOperation)和NSOperationQueue的优势
-(void)opDemo3{
NSBlockOperation *op1=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@&下载图片 %@&,[NSThread currentThread]);
NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@&修饰图片 %@&,[NSThread currentThread]);
NSBlockOperation *op3=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@&保存图片 %@&,[NSThread currentThread]);
NSBlockOperation *op4=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@&更新UI %@&,[NSThread currentThread]);
[op4 addDependency:op3];
[op3 addDependency:op2];
[op2 addDependency:op1];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
//设置同一时刻最大开启的线程数,这是NSOperationQueue特有的
[queue setMaxConcurrentOperationCount:2];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[[NSOperationQueue mainQueue]addOperation:op4];
(3)单例的实现(手写单例要求)dispatch_once运用,即重写类的allocWithZone方法
@implementation WPObject
+(instancetype)allocWithZone:(struct _NSZone *)zone{
static WPObject *
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
insta=[super allocWithZone:zone];
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致GCD的基本思想就是将操作(任务)放在队列中去执行
队列负责调度任务执行所在的线程以及具体的执行时间
队列的特点是先进先出,新添加至队列的操作(任务)都会排在队尾
GCD的函数都是以dispatch开头的,dispatch的意思是“分配、调度”
串行队列中的任务会按顺序执行
并行队列中的任务通常会并发执行,而且无法确定任务的执行顺序
dispatch_async表示异步操作,异步操作会新开辟线程来执行任务,而且无法确定任务的执行顺序
dispatch_sync表示同步操作,同步操作不会新开辟线程
在串行队列中执行同步任务:不会新建线程,按顺序执行任务(毫无用处)
在串行队列中执行异步任务,会新建线程,按顺序执行任务(非常有用)
在并行队列中执行同步任务:不会新建线程,按顺序执行任务(几乎没用)
在并行队列中执行异步任务:会新建多个线程,但是无法确定任务的执行顺序(有用,但是很容易出错)
全局队列:
全局队列是系统的,直接拿过来就可以用,与并行队列类似,但是不能指定队列的名字,调试时无法确认任务所在队列
在全局队列中执行同步任务:不会新建线程,按顺序执行任务
在全局队列中执行异步任务:会新建多个线程,但是无法确定任务的执行顺序
每一个应用程序只有一个主线程即只有一个主队列
为什么需要再主线程上执行任务呢?因为在ios开发中,所有UI的更新任务都必须在主线程上执行。
主队列中的操作都是在主线程中执行的,不存在异步的概念
主队列中添加的同步操作永远不会被执行(会死锁)
无论什么队列和什么任务,线程的创建和回收不需要程序员参与,由队列来负责,程序员只需要面对队列和任务。
GCD在后端管理这一个线程池,GCD不仅决定着Block代码块将在哪个线程中被执行,
而且还可以根据可用的系统资源对这些线程进行管理,从而让开发者从线程管理的工作中解放出来,
通过GCD这种集中的管理线程,缓解了大量的线程被创建的问题。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:38033次
排名:千里之外
原创:10篇
转载:63篇
(1)(2)(1)(3)(1)(1)(3)(2)(4)(1)(5)(5)(1)(1)(3)(3)(1)(5)(1)(1)(4)(6)(3)(5)(1)(9)(1)1.用户自定义线程队列,创建时很容易创建 注意创建时的第一个参数:标记值,方便调试查看
dispatch_queue_t serialqueue=dispatch_queue_create("serialqueue", DISPATCH_QUEUE_SERIAL);//串行线程队列
dispatch_queue_t concurrentqueue=dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);//并行线程队列
&2.创建之后那如何验证它是串行还是并行的呢?
dispatch_apply(5, concurrentqueue, ^(size_t index) {
NSLog(@"%ld",index);
dispatch_apply(5, serialqueue, ^(size_t index) {
NSLog(@"%ld",index);
&输出结果:
第一个循环输出无序第一个有序,可以看出第一个是多线程并行,第二哥是单线程串行。
(1)串行的验证:
dispatch_async(serialqueue, ^{
NSLog(@"1");
dispatch_async(serialqueue, ^{
NSLog(@"2");
dispatch_async(serialqueue, ^{
NSLog(@"3");
dispatch_async(serialqueue, ^{
NSLog(@"4");
dispatch_async(serialqueue, ^{
NSLog(@"5");
dispatch_async(serialqueue, ^{
NSLog(@"6");
dispatch_async(serialqueue, ^{
NSLog(@"7");
dispatch_async(serialqueue, ^{
NSLog(@"8");
dispatch_async(serialqueue, ^{
NSLog(@"9");
dispatch_async(serialqueue, ^{
NSLog(@"10");
dispatch_async(serialqueue, ^{
NSLog(@"11");
dispatch_async(serialqueue, ^{
NSLog(@"12");
dispatch_async(serialqueue, ^{
NSLog(@"13");
&输出结果:
可以看到输出结果连续。
(2)并行的验证:
dispatch_async(concurrentqueue, ^{
NSLog(@"1");
dispatch_async(concurrentqueue, ^{
NSLog(@"2");
dispatch_async(concurrentqueue, ^{
NSLog(@"3");
dispatch_async(concurrentqueue, ^{
NSLog(@"4");
dispatch_async(concurrentqueue, ^{
NSLog(@"5");
dispatch_async(concurrentqueue, ^{
NSLog(@"6");
dispatch_async(concurrentqueue, ^{
NSLog(@"7");
dispatch_async(concurrentqueue, ^{
NSLog(@"8");
dispatch_async(concurrentqueue, ^{
NSLog(@"9");
dispatch_async(concurrentqueue, ^{
NSLog(@"10");
dispatch_async(concurrentqueue, ^{
NSLog(@"11");
dispatch_async(concurrentqueue, ^{
NSLog(@"12");
dispatch_async(concurrentqueue, ^{
NSLog(@"13");
&输出结果:
由此可见:输出结果不连续。
3.从上面的两个输出结果可以看出:串行是在一个线程上执行任务,而并行是在多个线程上执行任务。
阅读(...) 评论()串行队列 分两种
创建一个主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
像主队列中添加任务
参数1 要添加的队列
参数2 要添加的任务
dispatch_async(mainQueue, ^{
NSLog(@&第一个任务,所在线程:%@, 是否是主线程:%d&, [NSThread currentThread], [NSThread currentThread].isMainThread);
dispatch_async(mainQueue, ^{
NSLog(@&第二个任务,所在线程:%@, 是否是主线程:%d&, [NSThread currentThread], [NSThread currentThread].isMainThread);
dispatch_async(mainQueue, ^{
NSLog(@&第三个任务,所在线程:%@, 是否是主线程:%d&, [NSThread currentThread], [NSThread currentThread].isMainThread);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(33 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@&延迟3秒执行&);
ull 是C语言的数值字面量 相当于 unsigned long long
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 55ull * NSEC_PER_SEC), mainQueue, ^{
NSLog(@&延迟5秒执行&);
综上:串行主队列 都在主线冲中进行任务 结束一个 才能进入下一个
[objc] view plaincopy
2.自定义队列
创建一个队列
参数1 自定义队列的标示符 名字
参数2 自定义队列的种类 串行
dispatch_queue_t myQueue = dispatch_queue_create(&com.wl.MyQueue&, DISPATCH_QUEUE_SERIAL);
dispatch_async(myQueue, ^{
for (int i = 0; i & 10; i++) {
NSLog(@&第一个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
dispatch_async(myQueue, ^{
for (int i = 10; i & 20; i++) {
NSLog(@&第二个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
dispatch_async(myQueue, ^{
for (int i = 20; i & 30; i++) {
NSLog(@&第三个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
[objc] view plaincopy
创建一个 并行队列
参数1 设置优先级 无优先级
参数2 预留参数 一般给0
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(myQueue, ^{
for (int i = 0; i & 10; i++) {
NSLog(@&第一个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
dispatch_async(myQueue, ^{
for (int i = 10; i & 20; i++) {
NSLog(@&第二个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
dispatch_async(myQueue, ^{
for (int i = 20; i & 30; i++) {
NSLog(@&第三个任务,所在线程:%@, 是否是主线程:%d-----%d&, [NSThread currentThread], [NSThread currentThread].isMainThread,i);
// 2.自定义队列,需要自己手动创建,并设置队列为并行
dispatch_queue_t myQueue = dispatch_queue_create(&com.lanou3g.ConcurrentQueue&, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
for (int i = 0; i & 10; i++) {
NSLog(@&第一个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
dispatch_async(myQueue, ^{
for (int i = 10; i & 20; i++) {
NSLog(@&第二个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
dispatch_async(myQueue, ^{
for (int i = 20; i & 30; i++) {
NSLog(@&第三个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
[objc] view plaincopy
- (void)group
// 创建分组
dispatch_group_t group = dispatch_group_create();
// 创建并行队列(全局队列)
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 把myQueue添加到分组group中,并且给myQueue添加任务
dispatch_group_async(group, myQueue, ^{
for (int i = 0; i & 10; i++) {
NSLog(@&第一个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
dispatch_group_async(group, myQueue, ^{
for (int i = 10; i & 20; i++) {
NSLog(@&第二个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
// 在分组所有任务执行完成之后,最后指向下面的任务
dispatch_group_notify(group, myQueue, ^{
// 回到主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@&当前的线程是: %@&, [NSThread currentThread]);
NSLog(@&所有数据下载完成.可以去刷新UI了&);
dispatch_group_async(group, myQueue, ^{
for (int i = 20; i & 30; i++) {
NSLog(@&第三个任务,所在线程:%@, 是否是主线程:%d~~~~~~~~~~~%d&, [NSThread currentThread], [NSThread currentThread].isMainThread, i);
[objc] view plaincopy
- (void)barrier
// 自己创建并行队列
dispatch_queue_t queue = dispatch_queue_create(&com.lanou3g.Barrier&, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@&玩家一读取完成&);
dispatch_async(queue, ^{
NSLog(@&玩家二读取完成&);
dispatch_async(queue, ^{
NSLog(@&玩家三读取完成&);
// 设置屏障
dispatch_barrier_async(queue, ^{
NSLog(@&等待其他玩家进入...&);
// 玩家一进入游戏
dispatch_async(queue, ^{
NSLog(@&玩家一进入游戏&);
// 玩家二进入游戏
dispatch_async(queue, ^{
NSLog(@&玩家二进入游戏&);
// 玩家三进入游戏
dispatch_async(queue, ^{
NSLog(@&玩家三进入游戏&);
dispatch_barrier_async(queue, ^{
// 回到主线程,更新UI
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@&------%d&, [NSThread currentThread].isMainThread);
NSLog(@&敌军即将在30秒后进入战场&);
只执行一次
- (void)onceBlock
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
NSLog(@&第一滴血&);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:659次
排名:千里之外
(1)(1)(1)(5)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&

我要回帖

更多关于 串行队列和并行队列 的文章

 

随机推荐