在多线程开发中我们经常会遇到这些概念:并发队列、串行队列、同步任务、异步任务。我们将这四个概念进行组合会有四种结果:串行队列+同步任务、串行队列+异步任务、并发队列+同步任务、并发队列+异步任务。我们对这四种结果进行解释:
1.串行队列+同步任务:不会开启新的线程,任务逐步完成。
2.串行队列+异步任务:开启新的线程,任务逐步完成。
3.并发队列+同步任务:不会开启新的线程,任务逐步完成。
4.并发队列+异步任务:开启新的线程,任务同步完成。
我们如果要让任务在新的线程中完成,应该使用异步线程。为了提高效率,我们还应该将任务放在并发队列中。因此在开发中使用最多的是并发队列+异步任务。看代码:
// 串行队列+同步任务
- (void)serialSyn{
dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"1---%@", [NSThreadcurrentThread]);
}
});
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"2---%@", [NSThreadcurrentThread]);
}
});
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"3---%@", [NSThreadcurrentThread]);
}
});
}
// 串行队列+异步任务
- (void)serialAsyn{
dispatch_queue_t queue =dispatch_queue_create("serial",DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"1---%@", [NSThreadcurrentThread]);
}
});
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"2---%@", [NSThreadcurrentThread]);
}
});
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"3---%@", [NSThreadcurrentThread]);
}
});
}
// 并发队列+同步任务
- (void)concurrenSyn{
dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"1---%@", [NSThreadcurrentThread]);
}
});
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"2---%@", [NSThreadcurrentThread]);
}
});
dispatch_sync(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"3---%@", [NSThreadcurrentThread]);
}
});
}
// 并发队列+异步任务
- (void)concurrentAsyn{
dispatch_queue_t queue =dispatch_queue_create("concurrent",DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"1---%@", [NSThreadcurrentThread]);
}
});
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"2---%@", [NSThreadcurrentThread]);
}
});
dispatch_async(queue, ^{
for (int i =0; i <3;
i ++) {
NSLog(@"3---%@", [NSThreadcurrentThread]);
}
});
}
输出结果分别为:
// 串行队列+同步任务
2017-12-09 15:50:18.427989+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:20.912799+0800 GCD[1044:27277] XPC connection interrupted
2017-12-09 15:50:21.429204+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:24.430559+0800 GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:25.431937+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:26.433460+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:27.433913+0800 GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:28.435443+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:29.435987+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
2017-12-09 15:50:30.437512+0800 GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
// 串行队列+异步任务
2017-12-09 16:08:03.242688+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:06.246989+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:09.249206+0800 GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:10.250193+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:11.250878+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:12.255908+0800 GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:13.258215+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:14.258708+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
2017-12-09 16:08:15.259192+0800 GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
// 串行队列+异步任务
2017-12-09 16:09:23.548551+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:25.547003+0800 GCD[1283:43153] XPC connection interrupted
2017-12-09 16:09:26.549830+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:29.550406+0800 GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:30.551134+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:31.552655+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:32.553861+0800 GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:33.555326+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:34.555842+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
2017-12-09 16:09:35.556267+0800 GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
// 并发队列+异步任务
2017-12-09 16:10:26.676320+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
2017-12-09 16:10:26.676320+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
2017-12-09 16:10:27.678310+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
2017-12-09 16:10:27.678316+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
2017-12-09 16:10:28.674756+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
2017-12-09 16:10:28.679805+0800 GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
2017-12-09 16:10:28.679798+0800 GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
2017-12-09 16:10:31.675355+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
2017-12-09 16:10:34.678046+0800 GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
看表格:
0.png注意:
在主队列中添加同步任务会产生死锁,进而导致程序崩溃。
代码:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"===========1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"===========2");
});
NSLog(@"===========3");
}
以上代码在打印出1之后就卡死在了dispatch_sync...的代码上。
串行队列异步任务中嵌套同步任务出现死锁
// 创建同步队列
dispatch_queue_t queue = dispatch_queue_create("serial", DISPATCH_QUEUE_SERIAL);
// 异步任务中嵌套同步任务
dispatch_async(queue, ^{
NSLog(@"====2");
// 无法打印5和3 死锁
dispatch_sync(queue, ^{
NSLog(@"====5");
});
NSLog(@"=====3");
});
NSLog(@"=====4");
本文来自 梁森森 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/u010105969/article/details/69914369?utm_source=copy
网友评论