在多线程开发中往往会遇到多个任务并发,但是还有任务之间具有依赖关系,比如下图:
使用NSOperationQueue要比GCD方便一些,代码更简洁。
1. 使用NSOperationQueue设置依赖
- (void)testOperation {
NSLog(@"开始----%@",[NSThread currentThread]);
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
NSBlockOperation *opA = [NSBlockOperation blockOperationWithBlock:^{
sleep(3);
NSLog(@"完成任务A----%@",[NSThread currentThread]);
}];
NSBlockOperation *opB = [NSBlockOperation blockOperationWithBlock:^{
sleep(2);
NSLog(@"完成任务B---%@",[NSThread currentThread]);
}];
NSBlockOperation *opC = [NSBlockOperation blockOperationWithBlock:^{
sleep(1);
NSLog(@"完成任务C---%@",[NSThread currentThread]);
}];
NSBlockOperation *opD = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"完成任务D---%@",[NSThread currentThread]);
}];
NSBlockOperation *opE = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"完成任务E---%@",[NSThread currentThread]);
}];
[opD addDependency:opA];
[opD addDependency:opB];
[opE addDependency:opB];
[opE addDependency:opC];
[queue addOperation:opA];
[queue addOperation:opB];
[queue addOperation:opC];
[queue addOperation:opD];
[queue addOperation:opE];
}
运行结果:
2019-07-15 17:07:57.918930+0800 xxtest[62847:2808690] 开始----{number = 1, name = main}
2019-07-15 17:07:58.922080+0800 xxtest[62847:2808777] 完成任务C----{number = 3, name = (null)}
2019-07-15 17:07:59.924180+0800 xxtest[62847:2808780] 完成任务B----{number = 4, name = (null)}
2019-07-15 17:07:59.924480+0800 xxtest[62847:2808792] 完成任务E----{number = 5, name = (null)}
2019-07-15 17:08:00.921409+0800 xxtest[62847:2808779] 完成任务A----{number = 6, name = (null)}
2019-07-15 17:08:00.921659+0800 xxtest[62847:2808778] 完成任务D----{number = 7, name = (null)}
2. 使用 @synchronized+dispatch_semaphore
//@property(nonatomic,strong) NSObject *mySyn;
//@property(nonatomic,strong) NSLock *lockD;
//@property(nonatomic,strong) NSLock *lockE;
-(void)synTest{
NSLog(@"开始----%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("com.xxx.customQueue", DISPATCH_QUEUE_CONCURRENT);
self.mySyn = [[NSObject alloc]init];
self.D_count = 0;
self.E_count = 0;
dispatch_semaphore_t D_sema = dispatch_semaphore_create(0);
dispatch_semaphore_t E_sema = dispatch_semaphore_create(0);
dispatch_async(queue, ^{
sleep(3);
NSLog(@"完成任务A----%@",[NSThread currentThread]);
@synchronized (self.mySyn) {
self.D_count = self.D_count + 1;
if (self.D_count==2) {
dispatch_semaphore_signal(D_sema);
}
}
});
dispatch_async(queue, ^{
sleep(2);
NSLog(@"完成任务B----%@",[NSThread currentThread]);
@synchronized (self.mySyn) {
self.D_count = self.D_count + 1;
if (self.D_count==2) {
dispatch_semaphore_signal(D_sema);
}
self.E_count = self.E_count + 1;
if (self.E_count==2) {
dispatch_semaphore_signal(E_sema);
}
}
});
dispatch_async(queue, ^{
sleep(1);
NSLog(@"完成任务C----%@",[NSThread currentThread]);
@synchronized (self.mySyn) {
self.E_count = self.E_count + 1;
if (self.E_count==2) {
dispatch_semaphore_signal(E_sema);
}
}
});
dispatch_async(queue, ^{
dispatch_semaphore_wait(D_sema, DISPATCH_TIME_FOREVER);
NSLog(@"完成任务D----%@",[NSThread currentThread]);
dispatch_semaphore_signal(D_sema);
});
dispatch_async(queue, ^{
dispatch_semaphore_wait(E_sema, DISPATCH_TIME_FOREVER);
NSLog(@"完成任务E----%@",[NSThread currentThread]);
dispatch_semaphore_signal(E_sema);
});
}
执行结果:
2019-07-15 17:11:18.540308+0800 xxtest[62873:2811422] 开始----{number = 1, name = main}
2019-07-15 17:11:19.544241+0800 xxtest[62873:2811459] 完成任务C----{number = 3, name = (null)}
2019-07-15 17:11:20.544484+0800 xxtest[62873:2811456] 完成任务B----{number = 4, name = (null)}
2019-07-15 17:11:20.544678+0800 xxtest[62873:2811529] 完成任务E----{number = 5, name = (null)}
2019-07-15 17:11:21.545102+0800 xxtest[62873:2811457] 完成任务A----{number = 6, name = (null)}
2019-07-15 17:11:21.545316+0800 xxtest[62873:2811458] 完成任务D----{number = 7, name = (null)}
3. 使用 dispatch_group+dispatch_semaphore
-(void)groupAndSema{
NSLog(@"开始----%@",[NSThread currentThread]);
dispatch_queue_t queue = dispatch_queue_create("com.xxx.customQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_semaphore_t B_sema = dispatch_semaphore_create(0);
dispatch_group_t groupAB =dispatch_group_create();
dispatch_group_async(groupAB,queue, ^{
sleep(3);
NSLog(@"完成任务A----%@",[NSThread currentThread]);
});
dispatch_group_async(groupAB,queue, ^{
sleep(2);
NSLog(@"完成任务B----%@",[NSThread currentThread]);
dispatch_semaphore_signal(B_sema);
});
dispatch_group_t groupBC =dispatch_group_create();
dispatch_group_async(groupBC,queue, ^{
dispatch_semaphore_wait(B_sema, DISPATCH_TIME_FOREVER);
});
dispatch_group_async(groupBC,queue, ^{
sleep(1);
NSLog(@"完成任务C----%@",[NSThread currentThread]);
});
dispatch_group_notify(groupAB,queue, ^{
NSLog(@"完成任务D----%@",[NSThread currentThread]);
});
dispatch_group_notify(groupBC,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSLog(@"完成任务E----%@",[NSThread currentThread]);
});
}
2019-07-16 11:07:23.328392+0800 xxtest[5590:141062] 开始----{number = 1, name = main}
2019-07-16 11:07:24.328872+0800 xxtest[5590:141167] 完成任务C----{number = 3, name = (null)}
2019-07-16 11:07:25.329991+0800 xxtest[5590:141154] 完成任务B----{number = 4, name = (null)}
2019-07-16 11:07:25.330212+0800 xxtest[5590:141166] 完成任务E----{number = 5, name = (null)}
2019-07-16 11:07:26.328750+0800 xxtest[5590:141156] 完成任务A----{number = 6, name = (null)}
2019-07-16 11:07:26.328931+0800 xxtest[5590:141156] 完成任务D----{number = 6, name = (null)}