iOS 多线程小结

2020-12-15  本文已影响0人  percivals

在 iOS 中其实目前有 4 套多线程方案,他们分别是:Pthreads、NSThread、GCD、 NSOperation & NSOperationQueue

Pthreads:常用于各种操作系统,基于c语言的框架,一般不用到

NSThread:手动管理生命周期,多用于调试使用

GCD: 分为任务和队列, 优势:底层实现,运行速度快

任务为要执行的代码,以block表示,分为同步任务和异步任务,同步任务会阻塞当前线程

1.队列分为串行和并行,串行队列一步步执行

2.队列组:将很多队列添加到一个队列组中,当组内所有任务执行完毕,有一个方法可以通知我们

串行队列:dispatch_queue_t queue = dispatch_queue_create(“nameID”,DISPATCH_QUEUE_SERIAL);

并行队列:dispatch_queue_t queue = dispatch_queue_create(“nameID”,DISPATCH_QUEUE_CONCURRENT);

串行队列中,系统提供了一个主队列:
dispatch_queue_t queue = dispatch_get_main_queue()

并行队列中,系统提供了一个全局并发队列:
dispatch_queue queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)

同步执行任务:
dispatch_sync(queue,^{
// 任务代码
})

异步执行任务:
dispatch_async(queue,^{
// 任务代码
})

注意:同步执行+主队列 在主线程中调用会死锁

3.栅栏方法

在一个队列中,栅栏任务会在之前任务执行完毕后执行,后续任务会在栅栏任务执行完毕后执行,即排序 任务一、任务二、栅栏任务、任务三、任务四的执行结果是 任务一、任务二异步执行,待执行完两者再执行栅栏任务,执行完毕再异步执行任务三、任务四

dispatch_barrier_async(queue,^{
// 栅栏任务
})

4.延时方法

在指定时间之后将任务添加到队列中

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0*NSEC_PER_SEC)), queue,^{
// 延时任务
})

5.只执行一次代码

保证某段代码在程序运行过程中只被执行一次,保证线程安全

如单例:

-(instance)shareManager
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
//只执行一次的代码

    _manager = [[Manager alloc] init];
});

return _manager;

}

6.线程组(队列组) dispatch_group

任务放到队列中,队列放到队列组中

dispatch_group_t group = dispatch_group_creat();

dispatch_group_async(group,queue,^{
// 任务1
})

dispatch_group_async(group,queue,^{
// 任务2
})

监听线程组内任务全部执行完毕 dispatch_group_notify

dispatch_group_notify(group,queue,^{
// 监听线程组内任务执行完毕后执行的任务
});

7.线程阻塞 dispatch_group_enter、dispatch_group_leave

阻塞线程等待前面的线程组内的任务执行完

dispatch_group_wait(group,DISPATCH_TIME_FOREVER);

dispatch_group_enter 标志着一个任务追加到 group,执行一次,相当于 group 中未执行完毕任务数+1
dispatch_group_leave 标志着一个任务离开了 group,执行一次,相当于 group 中未执行完毕任务数-1。

当 group 中未执行完毕任务数为0的时候,才会使dispatch_group_wait解除阻塞,以及执行追加到dispatch_group_notify中的任务。

8.信号量 dispatch_semaphore

•   保持线程同步,将异步执行任务转换为同步执行任务
•   保证线程安全,为线程加锁

dispatch_semaphore_create:创建一个Semaphore并初始化信号的总量

dispatch_semaphore_signal:发送一个信号,让信号总量加1

dispatch_semaphore_wait:可以使总信号量减1,当信号总量为0时就会一直等待(阻塞所在线程),否则就可以正常执行。

NSOperation和NSOperationQueue:NSOperation 和 NSOperationQueue 分别对应 GCD 的 任务 和 队列;将要执行的任务封装到一个 NSOperation 对象中,将此任务添加到一个 NSOperationQueue 对象中

NSOperation 只是一个抽象类,所以不能封装任务。但它有 2 个子类用于封装任务。分别是:NSInvocationOperation 和 NSBlockOperation 。创建一个 Operation 后,需要调用 start 方法来启动任务

除了上面的两种 Operation 以外,我们还可以自定义 Operation。自定义 Operation 需要继承 NSOperation 类,并实现其 main() 方法

任务创建完成后,添加到对应的NSOperationQueue队列中执行

NSOperation 有一个非常实用的功能,那就是添加依赖
[operation2 addDependency:operation1];

单例:

上一篇下一篇

猜你喜欢

热点阅读