4.3 NSThread->3.0 线程状态/线程生命周期

本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正。


本文相关目录:
==================== 所属文集:4.0 多线程 ====================
4.1 多线程基础->1.0 进程 & 线程
······················ 2.0 多线程简介
4.2 pthread
4.3 NSThread->1.0 创建线程
····················· 2.0 线程属性
····················· 3.0 线程状态/线程生命周期
····················· 4.0 多线程安全隐患
····················· 5.0 线程间通讯和常用方法
4.4 GCD->1.0 GCD简介和使用
·············· 2.0 线程间的通信
·············· 3.0 其他用法
·············· 4.0 GCD 的定时器事件
4.5 NSOperation->1.0 NSOperation简介
························ 2.0 NSOperationQueue
························ 3.0 线程间通信
························ 4.0 自定义NSOperation
4.6 RunLoop - 运行循环
===================== 所属文集:4.0 多线程 =====================


线程状态

  • 新建状态
  • 就绪状态/启动状态 : 线程在可调度线程池中
  • 运行状态
  • 阻塞状态/暂停线程 : 线程不在可调度线程池中,但是仍然存在内存中,只是不可用
  • 死亡状态 : 线程不在内存中

3.1 新建状态

(1)新建状态 : 实例化线程对象

说明:创建线程有多种方式,这里不做过多的介绍

NSThread *thread =[[NSThread alloc] initWithTarget:self
                                          selector:@selector(run)
                                            object:nil];
4.3 NSThread->3.0 线程状态/线程生命周期_第1张图片
新建状态.png

3.2 就绪状态 / 启动线程

(2)就绪状态 / 启动线程: ( 进入就绪状态 ->运行状态。当线程任务执行完毕,自动进入死亡状态 )

线程开启 : 线程进入可调度线程池

- 向线程对象发送 start 消息,线程对象被加入可调度线程池等待 CPU 调度
- detachNewThreadSelector 方法和 performSelectorInBackground 方法会直接实例化一个线程对象并加入可调度线程池
[thread start];
4.3 NSThread->3.0 线程状态/线程生命周期_第2张图片
就绪状态 / 启动线程.png
4.3 NSThread->3.0 线程状态/线程生命周期_第3张图片
可调度线程池.png

3.3 运行状态

(3)运行状态:

  • CPU 负责调度可调度线程池中线程的执行
  • 线程执行完成之前(死亡之前),状态可能会在就绪和运行之间来回切换
  • 就绪和运行之间的状态变化由 CPU 负责,程序员不能干预
运行状态.png
  • 当 CPU 调度当前线程 , 进入运行状态
  • 当 CPU 调度其他线程 , 进入就绪状态

3.4 阻塞状态 / 暂停线程

(4)阻塞状态 / 暂停线程 : 当满足某个预定条件时,可以使用休眠或锁阻塞线程执行

方法执行过程,符合某一条件时,可以利用 sleep 方法让线程进入 阻塞 状态

sleepForTimeInterval:    //休眠指定时长    (从现在起睡多少秒)
sleepUntilDate:          //休眠到指定日期 (从现在起睡到指定的日期)
@synchronized(self) { }   //互斥锁
(1)阻塞2秒
[NSThread sleepForTimeInterval:2]; // 阻塞状态

(2)以当前时间为基准阻塞4秒
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:4.0]; //从现在开始多少秒
[NSThread sleepUntilDate:date];  //睡眠多少秒

未阻塞前:


4.3 NSThread->3.0 线程状态/线程生命周期_第4张图片
未阻塞前.png

阻塞后 ——> 变为就绪状态


4.3 NSThread->3.0 线程状态/线程生命周期_第5张图片
阻塞后.png

线程处理阻塞状态时在内存中的表现情况:线程被移出可调度线程池,此时不可调度


4.3 NSThread->3.0 线程状态/线程生命周期_第6张图片
线程处理阻塞状态时在内存中的表现情况.png

3.5 死亡状态

(5)死亡状态 (一旦线程停止或死亡了,就不能再次开启任务 , 后续的所有代码都不会被执行 )

(1) 正常死亡

- 线程执行完毕
(2) 非正常死亡

- (自杀)      当满足某个条件后,在线程内部自己中止执行
- (被逼着死亡) 当满足某个条件后,在主线程给其它线程打个死亡标记,让子线程自行了断.

注意:在终止线程之前,应该注意释放之前分配的对象!
[NSThread exit]; //终止线程.强制停止线程
4.3 NSThread->3.0 线程状态/线程生命周期_第7张图片
死亡状态.png

内存情况 : 线程死亡后,线程对象从内存中移除

4.3 NSThread->3.0 线程状态/线程生命周期_第8张图片
内存情况.png

代码示例

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

  // 1.在主线程中创建一个子线程(实例化线程对象) ---> 新建状态
  NSThread *Th =
      [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];

  // 2.将 Th 线程加入到可调度线程池,等待CPU调度--->就绪状态
  [Th start];

  // 3.让主线程阻塞,让当前线程(主线程)休眠
  [NSThread sleepForTimeInterval:1.0];

  // 4.在主线程给 Th 线程打死亡标签
  [Th cancel]; //只是打了个标签,并没有执行,需要在子线程中
}

// Th 线程---> 运行状态
- (void)run {

  NSThread *huThread = [NSThread currentThread];

  CGMutablePathRef path = CGPathCreateMutable();

  for (int i = 0; i < 30; i++) {
    if ([huThread isCancelled]) {
      NSLog(@"good bye1");
      return; // --->非正常死亡(被逼着死亡)
    }

    if (i == 5) {
      [NSThread sleepForTimeInterval:3.0]; //--->huThread阻塞状态3秒
      // [NSThread sleepUntilDate:[NSDate distantFuture]]; // 睡到遥远的未来
      // [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]]; //线程睡到从现在开始后的2秒为止
    }

    if ([huThread isCancelled]) {
      NSLog(@"good bye2");
      return;
    }

    if (i == 20) {
      //清空资源
      CGPathRelease(path);

      //在调用下面方法之前,必须清空资源  非正常死亡--自杀(退出线程)
      [NSThread exit];
    }

    if ([huThread isCancelled]) {
      NSLog(@"good bye3");
      return;
    }
    NSLog(@"%d", i);
  }
} //--->huThread死亡状态  (正常死亡状态)

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

@end

本文源码 Demo 详见 Github
https://github.com/shorfng/iOS_4.0_multithreading.git





作者:蓝田(Loto)
出处:

如果你觉得本篇文章对你有所帮助,请点击文章末尾下方“喜欢”
如有疑问,请通过以下方式交流:
评论区回复微信(加好友请注明“+称呼”)发送邮件[email protected]



本文版权归作者和本网站共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

你可能感兴趣的:(4.3 NSThread->3.0 线程状态/线程生命周期)