两种特殊队列:全局并发队列、主队列
看代码:
串行队列+同步任务
- (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]);
}
});
}
打印结果
GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 1---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 2---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
GCD[1044:27175] 3---<NSThread: 0x600000073600>{number = 1, name = main}
由打印结果可知串行队列+同步任务是串行执行,且没有开启子线程
串行队列+异步任务
- (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]);
}
});
}
打印结果
GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 1---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 2---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
GCD[1252:41773] 3---<NSThread: 0x600000276ec0>{number = 3, name = (null)}
由打印结果可知串行队列+异步任务是串行执行,且只开启了一个子线程。
并发队列+同步任务
- (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]);
}
});
}
打印结果
GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 1---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 2---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
GCD[1283:42913] 3---<NSThread: 0x604000260540>{number = 1, name = main}
由打印结果可知并发队列+同步任务是串行执行,且没有开启子线程。
并发队列+异步任务
- (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]);
}
});
}
打印结果
GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
GCD[1309:44938] 3---<NSThread: 0x604000466c40>{number = 3, name = (null)}
GCD[1309:44937] 2---<NSThread: 0x60000066e380>{number = 4, name = (null)}
GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
GCD[1309:44935] 1---<NSThread: 0x60000066fa80>{number = 5, name = (null)}
由打印结果可知并发队列+异步任务是并发执行,且开启了多个子线程。
看表格:
注意:
在主队列中添加同步任务会产生死锁,进而导致程序崩溃。
代码:
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"===========1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"===========2");
});
NSLog(@"===========3");
}
以上代码在打印出1之后就卡死在了dispatch_sync...的代码上。
原因: viewDidLoad方法在主队列中,在viewDidLoad方法中将一个同步任务添加到主队列中,viewDidLoad方法要想执行完需要等待同在主队列中的同步任务执行完,而该同步任务要想执行完需要等待同在主队列中的viewDidLoad执行完,从而导致两个任务互相等待,造成了死锁。
如果在其他线程中执行同步任务就完全不会有问题。
串行队列异步任务中嵌套同步任务出现死锁
// 创建同步队列
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");
原因:同步队列中的两个任务相互等待,造成死锁。
2019.3.14
在主队列中添加同步任务造成死锁就是主线程和主队列的互相等待。
主队列中的任务一定是在主线程中执行的,但主线程可执行非主队列的队列上的任务。
异步执行有开启新线程的能力, 但有这种能力并不一定会利用这种能力。
线程不会无限开启。
异步任务+串行队列:无论有多少个异步任务,开启的线程也只有一个。在新线程中的所有任务也都是串行执行的。
系统会把主队列中的任务放到主线程中。
异步任务+主队列并不会开启新的线程。主线程中执行任务。