1.Dispatch Queue
队列分为串行队列和并行队列,队列全部符合FIFO的原则(先入先出)
串行队列内只有一个线程完成加到队列内的任务
并行队列内有多个线程完成加到队列内的任务
队列内的任务一定是按照先进先出的原则逐一开始的
串:[op1 start]->[op2 start]->[op3 start]->[op4 start]
并:[op1 start]->[op2 start]->[op3 start]->[op4 start]
只不过串行队列需要等待前一个任务完成开始下一个,而并行队列不需要等待.「因为串行队列只有一个线程在干活」
串:[op1 done]->[op2 done]->[op3 done]->[op4 done]
并:看心情_
- Main dispatch queue
dispatch_queue_t queue = dispatch_get_main_queue();
Main dispatch queue是串行队列
- global dispatch queue
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
global dispatch queue是并行队列
global dispatch queue有四个优先级:
DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_DEFAULT
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_BACKGROUND
- 自建串行队列
dispatch_queue_t serial_queue = dispatch_queue_create("com.pogong.www", DISPATCH_QUEUE_SERIAL);
- 自建并行队列
dispatch_queue_t concurrent_queue = dispatch_queue_create("com.pogong.www", DISPATCH_QUEUE_CONCURRENT);
2.同步异步
- dispatch_sync 同步
同步意味阻塞当前线程,任务完成才返回 - dispatch_async 异步
异步不阻塞当前线程,任务不用完成就返回了
3.混合讨论
//外围线程
dispatch_async(dispatch_get_main_queue(), ^{
//内部执行任务的线程
});
依照上面的格式:
外围线程 | 执行模式 | 执行队列 | 内部执行任务的线程 |
---|---|---|---|
主线程 | 同步 | 并行队列 | 主线程 |
主线程 | 异步 | 并行队列 | 多个次线程 |
主线程 | 同步 | 串行队列 | 主线程 |
主线程 | 异步 | 串行队列 | 单个次线程 |
次线程 | 同步 | 主队列 | 主线程 |
次线程 | 异步 | 主队列 | 主线程 |
执行队列为主队列:忽略同步异步,全在主线程执行.
可以看到,同步方法不一定在本线程,异步方法方法也不一定新开线程.
4.死锁
void (^myBlock)(void) = ^{
NSLog(@"Block中 ");
};
dispatch_sync(dispatch_get_main_queue(), myBlock);
主线程正在执行dispatch_sync()
,随后主队列中新增一个任务block.因为主队列是串行队列,所以主线程会在dispatch_sync()
结束后再执行block,但是dispatch_sync
是同步派发,要等block执行完才算是结束.在主队列中的两个任务互相等待,导致了死锁.
此处需要区分线程与队列:线程是跑任务的,队列是保存任务,并保证任务执行符合FIFO原则的.
将dispatch_sync
换成dispatch_async
就可以避免死锁
void (^myBlock)(void) = ^{
NSLog(@"Block中 ");
};
dispatch_async(dispatch_get_main_queue(), myBlock);
文章参考:
Objective-C高级编程:iOS与OS X多线程和内存管理
bestswifer iOS多线程编程——GCD与NSOperation总结
戴铭 细说GCD如何用
网友评论