在程序开发的时候,我们会经常使用到多线程,相信很多程序员对多线程这一块都很头疼,如果我们想用好多线程,就需要加深对多线程的理解,这样我们在使用的时候才会得心应手,所以在工作闲暇之余我总结了一些自己对多线程的理解,如有不足之处,请各位看客老爷多多指出.
言归正传,大家都知道在iOS开发中,有四种多线程技术的使用,block除外.即:
- pthread
- NSThread
- GCD
- NSOperation
因为pthread的使用难度较大,切线程的生命周期需要程序员自己管理,所以我在平时的工作中也很少用到这样的技术,由于本人能力有限,所以下面我只会分析和总结NSThread,GCD和NSOperation.
在正式总结之前有一点需要大家注意:
同一个方法内的代码,都是在相同线程执行的(block除外)
NSThread
- NSThread在创建之后需要手动启动,即start方法
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);
- detach方法为分离一个线程去执行方法,这个则为自动执行
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
- performSelectorInBackground也是自动执行,切为隐式创建线程
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);
前两种方法可以通过指定不同的target来执行不同类的@selector,而performSelectorInBackground方法是 NSObject 的分类方法,它会自动在后台执行@selector方法,performSelectorInBackground执行哪个类的方法取决于它的调用对象,所以不要看见target就写self,这也是很多新手常犯的错误
线程的状态
线程划分为物种状态,即:
- 创建
实例化线程对象 - 就绪
向线程对象发送 start 消息,线程对象被加入可调度线程池等待 CPU 调度
detach 方法和 performSelectorInBackground 方法会直接实例化一个线程对象并加入可调度线程池 - 运行
CPU 负责调度可调度线程池中线程的执行
线程执行完成之前,状态可能会在就绪和运行之间来回切换
就绪和运行之间的状态变化由 CPU 负责,程序员不能干预 - 阻塞
当满足某个预定条件时,可以使用休眠或锁阻塞线程执行
sleepForTimeInterval:休眠指定时长
sleepUntilDate:休眠到指定日期
@synchronized(self):互斥锁 - 死亡
- 正常死亡
线程执行完毕 - 非正常死亡
当满足某个条件后,在线程内部中止执行
[NSThread exit];
当满足某个条件后,在主线程中止线程对象
注意:在终止线程之前,应该注意释放之前分配的对象!
注意:线程从就绪和运行状态之间的切换是由 CPU 负责的,程序员无法干预
也就是说当 当前任务 加入到 可调度线程池之后 我们无法阻止当前线程的执行,只能在执行代码中提前处理好终止条件.
就先写到这,我会在后面的博客继续分析多线程技术和横纵向的对比.