在多线程开发中往往会遇到多个任务并发,但是还有任务之间具有依赖关系,比如下图:
任务依赖图
使用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] 开始----<NSThread: 0x600002dbe900>{number = 1, name = main}
2019-07-15 17:07:58.922080+0800 xxtest[62847:2808777] 完成任务C----<NSThread: 0x600002dc3780>{number = 3, name = (null)}
2019-07-15 17:07:59.924180+0800 xxtest[62847:2808780] 完成任务B----<NSThread: 0x600002dc37c0>{number = 4, name = (null)}
2019-07-15 17:07:59.924480+0800 xxtest[62847:2808792] 完成任务E----<NSThread: 0x600002dc59c0>{number = 5, name = (null)}
2019-07-15 17:08:00.921409+0800 xxtest[62847:2808779] 完成任务A----<NSThread: 0x600002dc5900>{number = 6, name = (null)}
2019-07-15 17:08:00.921659+0800 xxtest[62847:2808778] 完成任务D----<NSThread: 0x600002d35500>{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] 开始----<NSThread: 0x60000118f600>{number = 1, name = main}
2019-07-15 17:11:19.544241+0800 xxtest[62873:2811459] 完成任务C----<NSThread: 0x6000011081c0>{number = 3, name = (null)}
2019-07-15 17:11:20.544484+0800 xxtest[62873:2811456] 完成任务B----<NSThread: 0x6000011dc180>{number = 4, name = (null)}
2019-07-15 17:11:20.544678+0800 xxtest[62873:2811529] 完成任务E----<NSThread: 0x6000011f4d80>{number = 5, name = (null)}
2019-07-15 17:11:21.545102+0800 xxtest[62873:2811457] 完成任务A----<NSThread: 0x60000110b040>{number = 6, name = (null)}
2019-07-15 17:11:21.545316+0800 xxtest[62873:2811458] 完成任务D----<NSThread: 0x6000011fb180>{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] 开始----<NSThread: 0x600000fba880>{number = 1, name = main}
2019-07-16 11:07:24.328872+0800 xxtest[5590:141167] 完成任务C----<NSThread: 0x600000f3c680>{number = 3, name = (null)}
2019-07-16 11:07:25.329991+0800 xxtest[5590:141154] 完成任务B----<NSThread: 0x600000fdd240>{number = 4, name = (null)}
2019-07-16 11:07:25.330212+0800 xxtest[5590:141166] 完成任务E----<NSThread: 0x600000f3c6c0>{number = 5, name = (null)}
2019-07-16 11:07:26.328750+0800 xxtest[5590:141156] 完成任务A----<NSThread: 0x600000fcad40>{number = 6, name = (null)}
2019-07-16 11:07:26.328931+0800 xxtest[5590:141156] 完成任务D----<NSThread: 0x600000fcad40>{number = 6, name = (null)}
网友评论