软件编程
位置:首页>> 软件编程>> java编程>> 深入探究Java线程的状态与生命周期

深入探究Java线程的状态与生命周期

作者:淡沫初夏Zz  发布时间:2021-10-01 17:44:10 

标签:Java,线程,状态,生命周期

一、线程的状态

深入探究Java线程的状态与生命周期

NEW: 安排了工作, 还未开始行动
RUNNABLE: 可工作的. 又可以分成正在工作中和即将开始工作.
BLOCKED: 这几个都表示排队等着其他事情
WAITING: 这几个都表示排队等着其他事情
TIMED_WAITING: 这几个都表示排队等着其他事情
TERMINATED: 工作完成了

新建(初始)

当继承Thread类和实现了Runnable接口,就可以创建线程,新建一个对象就是初始状态

就绪(可运行)

  • 调用线程的start()方法,此线程进入可运行状态。

  • 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入可运行状态。

  • 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入可运行状态。

  • 锁池里的线程拿到对象锁后,进入可运行状态。

运行

可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码,就到了运行状态

阻塞

阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu 时间片,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu 时间片转到运行(running)状态

  • 当前线程T调用Thread.sleep()方法,当前线程进入阻塞状态。

  • 运行在当前线程里的其它线程t2调用join()方法,当前线程进入阻塞状态。

  • 等待用户输入的时候,当前线程进入阻塞状态

死亡

  • 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。

  • 在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常

二、线程的状态转移

NEW , RUNNABLE ,TERMINATED 状态的转移

使用 isAlive 方法判定线程的存活状态

public class ThreadStateTransfer {
   public static void main(String[] args) throws InterruptedException {
       Thread t = new Thread(() -> {
           for (int i = 0; i < 1000_0000; i++) {
           }
       }, "李四");
       System.out.println(t.getName() + ": " + t.getState());;
       t.start();
       while (t.isAlive()) {
           System.out.println(t.getName() + ": " + t.getState());;
       }
       System.out.println(t.getName() + ": " + t.getState());;
   }
}

yield() 方法,让出 CPU执行权

/**
* yield让出CPU执行权
*/
public class ThreadYield {
   public static void main(String[] args) {
       Thread thread  = new Thread(() ->{
           Thread t1 = Thread.currentThread();
           for (int i = 0; i < 10; i++) {
               //让出CPU执行权
               Thread.yield();
               System.out.println("执行了线程" + t1.getName());
           }
       },"张三");
       thread.start();
       //创建并启动线程
       new Thread(() -> {
           Thread t1 = Thread.currentThread();
           for (int i = 0; i < 10; i++) {
               System.out.println("执行了线程" + t1.getName());
           }
       },"李四").start();
   }

结论

yield 不改变线程的状态, 但是会重新去排队

三、线程的生命周期

  • 新建:创建线程对象

  • 就绪:线程有执行资格,没有执行权

  • 运行:有执行资格,有执行权

  • 阻塞:由于一些操作让线程改变了状态,没有执行资格,没有执行权,另一些操作可以把它给激活,激活处于就绪状态

  • 死亡:线程对象变成垃圾,等待被回收

来源:https://blog.csdn.net/qq_55660421/article/details/123735080

0
投稿

猜你喜欢

  • Android里判断是否可以上网,常用的是如下方法:/** * 检测网络是否连接 * * @return */private boolea
  • 本文实例为大家分享了Android实现简易QQ界面的具体代码,供大家参考,具体内容如下要求: (1)与QQ界面控件数目、样式相同 (2)与Q
  • log4j配置失效日志中打印Debug信息最近发布项目的时候发现控制台打印的日志较往常多了很多,仔细一看,debug和info信息也赫然在列
  • 如下所示:Ctrl+1或F2快速修复Ctrl+D快捷删除行Shift+Enter 快速切换到下一行,在本行的任何位置都可Ctrl+F11快速
  • 解决My eclipse 工程发布时端口占用问题如果运行后如图的错,需要进行如下操作来解决:a:打开cmd,输入netstat -ano 找
  • 本文以实例形式讲述了C#生成Word记录的方法,具体实现代码如下:private void button1_Click(object sen
  • Servlet:在Servlet中拼接html内容JSP:在html中拼接javaJSP+JavaBean:利用javaBean将大量的代码
  • 背景先上图由此可见,非自旋锁如果拿不到锁会把线程阻塞,直到被唤醒;自旋锁拿不到锁会一直尝试为什么要这样?好处阻塞和唤醒线程都是需要高昂的开销
  • Spring P标签的使用Spring的p标签是基于XML Schema的配置方式,目的是为了简化配置方式。由于Spring的p标签是spr
  •  在开发中,我们经常使用到ListView这个控件。Android的API也提供了许多创建ListView适配器的快捷方式。例如A
  • 要理解实现原理,必须把线程池的几个参数彻底搞懂,不要死记硬背一、线程池参数1、corePoolSize(必填):核心线程数。2、maximu
  • 本文实例讲述了C#面向对象编程之猜拳游戏实现方法。分享给大家供大家参考。具体实现方法如下:1.需求现在要制作一个游戏,玩家与计算机进行猜拳游
  • Excelapache 为 java开发者们提供了一套excel表格读写的工具:POI ,对于一个小白来说每次读写使用POI需要写一套复杂的
  • 本文实例为大家分享了使用ScrollRect制作翻页的具体代码,供大家参考,具体内容如下1.标准的层级结构 ScrollRect->V
  • 今天来学习总结一下,Android 后添加的一些新的组件和UI效果,Material Dialog,SwipeRefreshLayout,L
  • 废话不多说了额,直接给大家贴代码了,具体代码如下所示:/**   * 下载指定路径的文件,并写入到指定的位置   * &
  • 本文实例为大家分享了java实现字符串反转的具体代码,供大家参考,具体内容如下1.需求:定义一个方法,实现字符串反转。键盘录入一个字符串,调
  • 类和结构的区别:1.一个是引用类型一个是值类型Class是引用类型,继承自System.Object类Struct是值类型,继承自Syste
  • 关于死信队列在大多数的MQ中间件中,都有死信队列的概念。死信队列同其他的队列一样都是普通的队列。在RabbitMQ中并没有特定的“死信队列”
  • 引入字体首先在项目中创建fonts目录,然后将将ttf文件放到该目录下,然后在pubspec文件中添加该字体文件,如:...flutter:
手机版 软件编程 asp之家 www.aspxhome.com