美文网首页多线程程序员iOS Developer
4.3 NSThread->3.0 线程状态/线程生命周期

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

作者: 蓝田_Loto | 来源:发表于2016-04-15 14:19 被阅读350次

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


本文相关目录:
==================== 所属文集: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];
新建状态.png

3.2 就绪状态 / 启动线程

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

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

- 向线程对象发送 start 消息,线程对象被加入可调度线程池等待 CPU 调度
- detachNewThreadSelector 方法和 performSelectorInBackground 方法会直接实例化一个线程对象并加入可调度线程池
[thread start];
就绪状态 / 启动线程.png 可调度线程池.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];  //睡眠多少秒

未阻塞前:


未阻塞前.png

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


阻塞后.png

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


线程处理阻塞状态时在内存中的表现情况.png

3.5 死亡状态

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

(1) 正常死亡

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

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

注意:在终止线程之前,应该注意释放之前分配的对象!
[NSThread exit]; //终止线程.强制停止线程
死亡状态.png

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

内存情况.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)
出处: 简书

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



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

相关文章

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

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

  • 线程的学习总结

    我打算从线程得生命周期开始总结多线程: 线程的生命周期: 新建状态:线程对象创建之后,线程进入新建状态. 就绪状态...

  • Java知识梳理六

    一、Java多线程一 1.谈谈线程的生命周期和状态转移 关于线程生命周期的不同状态,在Java 5以后,线程...

  • java多线程基本概念(一)

    线程生命周期 说明线程工共包含5个状态: 新建状态new:调用线程构造方法创建线程后,线程进入新建状态; 就绪状态...

  • 4.3 NSThread->1.0 创建线程

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

  • 4.3 NSThread->2.0 线程属性

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

  • 【问答】Java多线程

    线程的状态,画一个线程的生命周期状态图 线程状态:NEW,未启动的线程;RUNNABLE,运行中,包括就绪状态和运...

  • Java基础知识(三)

    一、线程状态转化 线程状态生命周期如下: 新建状态(New):新创建了一个线程对象。 就绪状态(Runnable)...

  • 多线程知识点整理

    1、多线程基础 线程的生命周期(状态)NEW:就绪状态Java线程刚刚被创建,调用start()方法之后不代表线程...

  • 多线程-线程生命周期

    线程总共有6个生命周期状态,线程状态可以通过thread.getState()查看 线程状态是Thread.Sta...

网友评论

    本文标题:4.3 NSThread->3.0 线程状态/线程生命周期

    本文链接:https://www.haomeiwen.com/subject/bidnlttx.html