iOS多线程的了解
其实想写多线程这一篇呢,不是自己真的在实战上面用到过而是刚好看了几篇博客感觉收藏了很久了,应该输出一点东西了不然感觉没留下点什么白看了。
其实如果不是业务等因素的需要,多线程的使用真的没有什么好处,消耗时间,降低效率。
在这里要区分两个词:并发(concurrent)跟并行(parallelism)
并发指的是一种经常出现,无可避免的现象。它表达的是“多个任务同时发生,需要被对待”这一现象。它的侧重点在于“发生了”
并行指的是同时处理多个任务的技术。它是展示一种能够同时处理多个任务的能力,侧重点在于“运行”。
多线程采用的是并行技术,提高了执行的效率,开辟多个线程,将计算机的多个CPU同时投入使用,处理不同的任务。
NSThread
这是一个已经被苹果不太建议使用了的方式,其一是因为管理多线程太麻烦,其二是不会不会自动添加autoreleasepool。不过它创建一个线程来说还是比较简单的
[NSThread currentThead];
总结—->麻烦。
NSOperation
- 1、使用起来比GCD简单,可提供取消任务队列之中的任务,
- 2、使用起来可不用关心线程以及线程的生命周期。
- 3、并发队列,异步执行(多个线程,无序执行)。
其子类常见的有 NSInvocationOperation:较少使用;NSBlockOperation:最常使用;
自定义子类继承NSOperation,实现内部相应的方法:很少使用(几乎不用)。并且只有将operation放到一个NSOperationQueue中,才会异步执行操作。
//常用的操作线程(同步)
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^(){
DebugLog(@"%@",[NSThread currentThread]);
}];
/// 开始执行任务
[operation start];
// 假设添加了如下操作,开启新线程异步调用
[operation addExecutionBlock:^() {
DebugLog(@"1:%@", [NSThread currentThread]);
}];
[operation addExecutionBlock:^() {
DebugLog(@"2:%@", [NSThread currentThread]);
}];
//取消任务
[operation cancel];
NSOperation的新特性中有一项是:设置依赖
operation2.addDependency(operation1)
需要注意的是NSOperationQueue之间相互依赖的话会造成死锁。
GCD(Grand Central Dispatch)
GCD以块为基本单位,执行一个任务可以等于执行一个代码块,其中有两个概念:“队列”和“执行方式”。
队列:
- 串行队列—先入先出,只执行一个任务
- 并行队列—先入先出,可以形成多个任务并发
- 主队列—特殊的串行任务,一定在主线程执行
执行方式:
- 同步执行
异步执行
| 同步执行 | 异步执行——————- | —————- | ————-
串行队列 | 在当前线程上依次执行队列的各个任务,不创建新线程 | 在非主线程的一个线程(新建线程)依次执行任务
并行队列 | 在当前线程执行各个任务,不创建新线程 | 当前线程外的每一个任务新建线程执行,
全局队列 –> dispatch get global_queue 本质上是Concurrent Diapatch Queue |
主队列 | 主线程中依次执行,会阻塞线程 | 主线程中依次执行,会阻塞线程
队列操作的方法
//异步操作,再回主线程更新
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
DebugLog(@"异步线程");
dispatch_async(dispatch_get_main_queue(), ^{
DebugLog(@"异步主线程");
});
});
dispatch_after
最常用的用来做延迟执行处理的GCD方法。
double delay = 1.5f;
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^(void){
//延迟两秒结束后的操作
});
dispatch_group
监听并发队列中任务的完成情况,就可以用到group,因为并发情况下并不知道哪一个是最后执行的,所以无法单独进行监听。利用dispatch_group_create()创建一个组。
dispatch_suspend & dispatch_resume
队列的挂起及恢复队列,我们甚至可以在不同的线程对这个队列进行挂起和恢复,因为GCD是对队列的管理。
dispatch_once
这个函数大部分时间是用来创建一个单例:
+ (instancetype)sharedInstance {
static dispatch_once_t once;
static id sharedInstance;
dispatch_once(&once, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
dispatch_ semaphore_t
信号量用于控制并发的数量,只在全局队列和并行队列中使用。
dispatch_semaphore_signal:发送信号
dispatch_semaphore_create:创建一个信号
dispatch_semaphore_wait:等待信号
NSOperation与GCD的两者的一个比较
- GCD将任务添加到队列之中,并且指定任务执行的方式(同步-异步),同时若要停止加入队列中的任务需要添加较为复杂的逻辑代码,可以设置队列的优先级别。
NSOperation将异步操作添加到队列中,是对GCD的一个封装,更加面向对象,对于添加到队列中而又尚未执行的任务,可以比较方便的取消它。
写在最后
写了好几天,边写边重新理解多现场的一些东西,还是收获的比较多的,虽然项目上没什么机会用到多线程,但是还是学一点储备着,总归还是有些用处的。