iOS 实现并发和串行任务

作者: 一只长毛猫 | 来源:发表于2017-08-24 14:42 被阅读1289次
串行任务

场景:现有3个耗时任务A,B,C 需要依次有序执行。
分析:为了不阻塞主线程,只能异步依次执行任务A,B,C

方式一:GCD串行队列 实现串行任务

特点:只需开启一个线程,串行执行多个任务

//创建串行队列  (DISPATCH_QUEUE_SERIAL:串行) (DISPATCH_QUEUE_CONCURRENT:并发)
dispatch_queue_t  queue = dispatch_queue_create("com.fw.queue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        sleep(1);
        NSLog(@"任务A  thread:%@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(1);
        NSLog(@"任务B  thread:%@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(1);
        NSLog(@"任务C  thread:%@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{    
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"任务执行完毕,回到主线程 thread:%@",[NSThread currentThread]); 
        });
        
    });
    NSLog(@"结束");

打印结果

结束
2017-08-24 11:34:28.368057+0800 UIViewTest[27526:7523798] 结束
2017-08-24 11:34:29.376597+0800 UIViewTest[27526:7524243] 任务A  thread:<NSThread: 0x170279080>{number = 5, name = (null)}
2017-08-24 11:34:30.379257+0800 UIViewTest[27526:7524243] 任务B  thread:<NSThread: 0x170279080>{number = 5, name = (null)}
2017-08-24 11:34:31.384996+0800 UIViewTest[27526:7524243] 任务C  thread:<NSThread: 0x170279080>{number = 5, name = (null)}
2017-08-24 11:34:31.385371+0800 UIViewTest[27526:7523798] 任务执行完毕,回到主线程 thread:<NSThread: 0x17007a240>{number = 1, name = main}

可以看出任务A,B,C 是在同一个线程中,被一次执行的。执行完毕后,又可以回到主线程。

方式二:GCD后台线程+条件锁 实现串行任务

特点:需开启多个线程,利用条件锁依次执行

NSConditionLock  *lock = [[NSConditionLock alloc]initWithCondition:1];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    [lock lockWhenCondition:3];
    sleep(1);
    NSLog(@"任务C  thread:%@",[NSThread currentThread]);
    [lock unlockWithCondition:4];
});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    [lock lockWhenCondition:2];
    sleep(1);
    NSLog(@"任务B  thread:%@",[NSThread currentThread]);
    [lock unlockWithCondition:3];
});

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    
    [lock lockWhenCondition:1];
    sleep(1);
    NSLog(@"任务A  thread:%@",[NSThread currentThread]);
    [lock unlockWithCondition:2];
    
});

NSLog(@"结束");

打印结果

2017-08-24 11:42:39.911399+0800 UIViewTest[27529:7528485] 结束
2017-08-24 11:42:40.919128+0800 UIViewTest[27529:7528837] 任务A  thread:<NSThread: 0x170274e80>{number = 6, name = (null)}
2017-08-24 11:42:41.924922+0800 UIViewTest[27529:7528592] 任务B  thread:<NSThread: 0x170274600>{number = 7, name = (null)}
2017-08-24 11:42:42.926247+0800 UIViewTest[27529:7528836] 任务C  thread:<NSThread: 0x170263f00>{number = 8, name = (null)}

可以看出,任务A,B,C是按顺序执行的,每个任务都是在不同的线程中执行的。

方式三:NSOperationQueue

特点:若果添加依赖关系,那么多个任务在同一个线程中完成。如果没有依赖关系,那么多个任务在多个线程中完成

NSOperationQueue  *queue = [[NSOperationQueue alloc]init];


NSBlockOperation *opA = [NSBlockOperation blockOperationWithBlock:^{
    sleep(1);
    NSLog(@"任务A  thread:%@",[NSThread currentThread]);
}];

NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{
    sleep(1);
    NSLog(@"任务B  thread:%@",[NSThread currentThread]);
}];

NSBlockOperation *opC = [NSBlockOperation blockOperationWithBlock:^{
    sleep(1);
    NSLog(@"任务C  thread:%@",[NSThread currentThread]);
}];

//添加依赖关系,保证执行顺序
[opC addDependency:opB];
[opB addDependency:opA];

 [queue addOperation:opB];
 [queue addOperation:opC];
 [queue addOperation:opA];   

执行结果

2017-08-24 13:03:50.129224+0800 UIViewTest[27599:7554889] 任务A  thread:<NSThread: 0x170064480>{number = 3, name = (null)}
2017-08-24 13:03:51.132080+0800 UIViewTest[27599:7554889] 任务B  thread:<NSThread: 0x170064480>{number = 3, name = (null)}
2017-08-24 13:03:52.133824+0800 UIViewTest[27599:7554889] 任务C  thread:<NSThread: 0x170064480>{number = 3, name = (null)}
并发任务

特点:开启多条线程,同时执行多个任务。

方式一:采用dispatch_group,可以获取所有任务执行完毕的通知

场景:同时执行三个任务,所有任务执行完毕后,调用者可以得到通知。
dispatch_group是GCD的一项特性,能够给任务分组。调用者可以等待这组任务执行完毕,也可以在提供回调函数之后继续往下执行。这组任务完成时,调用者会得到通知。

//创建分组
dispatch_group_t dispatchGroup = dispatch_group_create();
//获取队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//添加并发任务
for (int i=1; i<=3; i++) {
    
    dispatch_group_async(dispatchGroup, queue, ^{
        
        sleep(1);
        NSLog(@"任务%d  thread:%@",i,[NSThread currentThread]);
    });
}
//任务执行完毕后,获取通知
dispatch_group_notify(dispatchGroup, queue, ^{
    
    NSLog(@"执行完毕  thread:%@",[NSThread currentThread]);
    
});

打印结果

2017-08-24 14:15:26.971016+0800 UIViewTest[27661:7571605] 任务1  thread:<NSThread: 0x170070d40>{number = 3, name = (null)}
2017-08-24 14:15:26.971405+0800 UIViewTest[27661:7571541] 任务2  thread:<NSThread: 0x170070d00>{number = 4, name = (null)}
2017-08-24 14:15:26.971735+0800 UIViewTest[27661:7571606] 任务3  thread:<NSThread: 0x170064440>{number = 5, name = (null)}
2017-08-24 14:15:26.971984+0800 UIViewTest[27661:7571606] 执行完毕  thread:<NSThread: 0x170064440>{number = 5, name = (null)}

从结果可以看出,最后的一个任务3执行完毕后,接着在同一个线程里,通知了调用者,所有任务执行完毕。

方式二:利用并发队列,直接执行并发任务

特点:不能获取所有任务执行完毕的通知

//串行:DISPATCH_QUEUE_SERIAL
//并发 DISPATCH_QUEUE_CONCURRENT

dispatch_queue_t  queue = dispatch_queue_create("com.fw.queue", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{
    sleep(1);
    NSLog(@"任务A  thread:%@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
    sleep(1);
    NSLog(@"任务B  thread:%@",[NSThread currentThread]);
});

dispatch_async(queue, ^{
    sleep(1);
    NSLog(@"任务C  thread:%@",[NSThread currentThread]);
});
NSLog(@"结束");

上面代码中的queue 也可以用GCD常用后台线程替换

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

打印结果

2017-08-24 14:33:35.523264+0800 UIViewTest[27666:7575286] 结束
2017-08-24 14:33:36.530702+0800 UIViewTest[27666:7575315] 任务A  thread:<NSThread: 0x17026f240>{number = 3, name = (null)}
2017-08-24 14:33:36.531057+0800 UIViewTest[27666:7575311] 任务B  thread:<NSThread: 0x17026f280>{number = 4, name = (null)}
2017-08-24 14:33:36.531344+0800 UIViewTest[27666:7575314] 任务C  thread:<NSThread: 0x17026f180>{number = 5, name = (null)}

可以看出三个任务,都在同一时刻完成

相关文章

  • iOS 实现并发和串行任务

    串行任务 场景:现有3个耗时任务A,B,C 需要依次有序执行。分析:为了不阻塞主线程,只能异步依次执行任务A,B,...

  • 多线程

    iOS中的几种多线程GCD1、GCD分为任务和队列,任务(同步,异步)队列(串行,并发),同步串行,同步主队列的情...

  • iOS 的串行队列和并发队列中的任务是如何执行的

    我们都知道队列有串行队列和并发队列,主队列就属于串行队列,串行队列里面的任务是按顺序执行,并发队列里的任务是并发执...

  • iOS开发之GCD并发队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 03 ...

  • iOS开发多线程之GCD

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 GCD...

  • iOS开发之GCD同步任务加强

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 004...

  • iOS开发之GCD串行队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 实例d...

  • GCD队列使用

    使用GCD前,先对队列总结一下: 串行和并发 GCD中队列分为两种:串行队列、并发队列。串行队列:任务按在队列里的...

  • iOS线程、队列与死锁

    iOS中关于线程和队列,有一些概念:队列、串行队列、并发队列、主线程、主队列、任务、同步、异步。这些概念的意义和联...

  • GCD学习总结

    GCD容易混淆的概念 任务,同步,异步 ,串行队列,并发队列 任务就是要做的事情 同步和异步是用来执行任务的 串行...

网友评论

本文标题:iOS 实现并发和串行任务

本文链接:https://www.haomeiwen.com/subject/tggsdxtx.html