线程、任务和队列的概念
类型 | 概念 |
---|---|
线程 | 程序执行任务的最小调度单位 |
任务 | 在GCD中,任务就是block中要执行的代码块 |
队列 | 存放任务的一个数组 |
异步、同步 & 并行、串行的特点
名称 | 特点 |
---|---|
异步执行 | 语句执行结束的顺序和语句执行开始的顺序不一定相同,具备有开启新线程的能力 |
同步执行 | 语句执行结束的顺序和语句执行开始的顺序相同,不具备开启新线程的能力 |
并行队列 | 队列中的任务同时执行 |
串行队列 | 队列中的任务按添加顺序执行(先进先出) |
组合
|并行队列|串行队列 |主队列
----|----|----|----
异步执行| 开启多个线程,任务同时执行|开启一个新线程,任务按顺序执行|不开启新线程任务按顺序执行
同步执行|不开启新线程,任务按顺序执行|不开启新线程,任务按顺序执行|会因为任务互相等待,造成死锁
代码详解
异步执行+并行队列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延时代码的执行结果是:1 3 2
打开延时代码的执行结果是:1 2 3
由此我们可以得知dispatch_async当中的任务在另一个线程中异步执行,由于我们无法得知在RunLoop中两个线程的执行顺序,所以结果可以是132和123
异步执行+串行队列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
//[NSThread sleepForTimerInterval:5];
NSLog(@"2");
})
dispatch_async(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"3");
})
}
屏蔽延时代码的执行结果是:1 2 3
打开延时代码的执行结果是:1 2 3
由此我们可知dispatch_async当中的多任务在同一个线程中根据添加进队列的顺序同步执行
异步执行+主队列
- (void)testGCD {
NSLog(@"1");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延时代码的执行结果是:1 3 2
打开延时代码的执行结果是:1 3 2
主队列的任务只能在主线程中执行,所以加进dispatch_async的任务会根据添加进主队列的顺序同步执行
同步执行+并行队列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_get_global_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延时代码的执行结果是:1 2 3
打开延时代码的执行结果是:1 2 3
由于dispatch_sync没有开启新线程的能力,所以所有任务按照添加顺序在主线程中按顺序同步执行
同步执行+串行队列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
//[NSThread sleepForTimerInterval:5];
NSLog(@"2");
})
dispatch_sync(dispatch_queue_create("testGCD", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"3");
})
}
屏蔽延时代码的执行结果是:1 2 3
打开延时代码的执行结果是:1 2 3
原因同上,只要是没有开启新线程,在主线程中任务就得按照添加顺序执行
同步执行+主队列
- (void)testGCD {
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
})
//[NSThread sleepForTimerInterval:5];
NSLog(@"3");
}
屏蔽延时代码的执行结果是:死锁
打开延时代码的执行结果是:死锁
主队列的任务要按照添加顺序执行,即132,而同步执行是按照代码添加顺序执行,即123。所以2在等待3执行结束,3在等待2执行结束,结果就造成了死锁
网友评论