Java 线程的几种状态

一、 线程的状态

  状态是针对当前的线程调度的情况来描述的。因为线程是调度的基本单位,所以状态更应该是线程的属性。在Java中线程的状态一共有六种:

1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
3. 阻塞(BLOCKED):表示线程阻塞于锁。
4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
6. 终止(TERMINATED):表示该线程已经执行完毕。

二、状态间相互转换

 NEW(线程对象刚创建,PCB 还未创建)调用了 start 真正的创建了线程,此时状态变为RUNNABLE(线程可以随时参加调度),线程执行完 run 方法以后,PCB被释放,但是线程对象还在,此时状态为 TERMINATED。三个阻塞等待都是由RUNNABLE切换而来。具体联系如下图所示:

三、状态详细说明

3.1  初始状态(NEW)

实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。

public class demo {public static void main(String[] args) {Thread t1 = new Thread(()->{});System.out.println(t1.getState());}
}

3.2 运行状态(Runnable) 


Runnable 包括了操作系统线程中的 Running(运行中)和 Ready(就绪)
线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start()方法,该状态的线程位于可运行线程池中,等待被线程调度选中,获取 CPU 的使用权,也就是说有了被 CPU 运行的资格Running(运行中) 就绪状态的线程在获得 CPU 时间片后转换为运行中(Running)

public class demo {public static void main(String[] args) {Thread t1 = new Thread(()->{});t1.start();System.out.println(t1.getState());}
}

3.3 等待状态(Waiting)

这种状态的线程不会被分配 CPU 执行时间,不给过无需等待被他其他线程显示地唤醒,在一定时间之后他们会被系统自动唤醒

public class demo {public static void main(String[] args) throws InterruptedException {Object ob = new Object();Thread t1 = new Thread(()->{synchronized (ob){try {ob.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();Thread.sleep(1000);//这里sleep是为了避免主函数运行过快,显示RunnableSystem.out.println(t1.getState());}
}

3.4 阻塞状态(Blocked)

个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入输出操作时,将让出CPU并暂时中止自己的执行,进入堵塞状态。

在可执行状态下,如果调用sleep()、suspend()、wait()等方法,线程都将进入阻塞状态。阻塞时,线程不能进入排队队列,只能当引起阻塞的原因被消除后,线程转入就绪状态,重新到就绪队列中排队等待,这时被CPU调度选中后会从原来停止的位置开始继续执行。

记住:阻塞被消除后是回到就绪状态,不是运行状态。

public class demo {synchronized public static void func() {try {Thread.sleep(1000000);} catch (InterruptedException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{func();});Thread t2 = new Thread(()->{func();});
//t2先获得锁,t1只能阻塞等待t2.start();t1.start();System.out.println(t2.getState());System.out.println(t1.getState());}
}

 3.5 .超时等待状态(Timed Waiting)

处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。

public class demo {public static void main(String[] args) throws InterruptedException {Object ob = new Object();Thread t1 = new Thread(()->{synchronized (ob){try {ob.wait(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();Thread.sleep(1000);//这里sleep是为了避免主函数运行过快,显示RunnableSystem.out.println(t1.getState());}
}

3.6 终止状态(Terminated)

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

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

public class demo {public static void main(String[] args) throws InterruptedException {Object ob = new Object();Thread t1 = new Thread(()->{});t1.start();Thread.sleep(1000);//这里sleep是为了让线程运行完毕,避免主函数运行过快显示RunnableSystem.out.println(t1.getState());}
}

四、 拓展:

问:线程状态 RUNNABLE 如何变为 BLOCKED? 
答:
线程状态变为阻塞有多种原因:可能调用 wait () 方法进入等待池,可能执行同
步方法 / 同步代码块进入等锁池,可能调用了 sleep ()/join () 等待休眠或其他
线程结束,可能发生了 I/O 中断等。

问: 什么是线程池? 为什么要使用它?

答:创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那么响应时间会变长,而且一个进程能创建的线程数有限。为了避免这些问题,在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程。从 JDK1.5 开始,Java API 提供了 Executor 框架让你可以创建不同的线程池。比如单线程池,每次处理一个任务;数目固定的线程池或者是缓存线程池(一个适合很多生存期短的任务的程序的可扩展线程池)。

问:什么是死锁?如何避免死锁?

答:死锁是指多个线程相互等待对方释放资源而无法继续执行的情况。要避免死锁,可以采用避免策略,比如按照固定的顺序获取锁,或者设置超时时间来放弃获取锁。


                        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/4096.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动静态库以及动态链接

文章目录 静态库制作静态库如何使用静态库 动态库动态库的制作动态库的使用动态链接 库是给别人用的,所以库中一定不存在main函数。库一般会有lib前缀和后缀,去掉前缀和后缀才是库名。 静态库 静态库(.a):程序在编译…

C++|对象与const

目录 常对象 常对象的声明 性质 数据成员不能被修改 常对象不能调用非const成员函数 const型成员函数 常对象成员 常数据成员 常成员函数 注意 总结 const型数据成员 const型成员函数 常对象 指针与const 指向对象的常指针 应用场景 指向常对象的指针 指向常…

Swagger3.0(Springdoc)日常使用记录

文章目录 前言一、默认地址二、注解OperationTag 三、SpringBoot基础配置四、Swagger导入apifox五、Swagger其他配置六 knife4j 参考文章 前言 本文并不是Swagger的使用教程,只是记录一下本人的操作,感兴趣的可以看下 一、默认地址 http://localhost:…

【1731】jsp 房租跟踪监控管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 房租跟踪监控管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysq…

Java 基础常见面试题整理

目录 1、java的基本数据类型有哪些?2、java为什么要有包装类型?3、String a "123" 和 String a new String("123") 区别?4、String、StringBuilder和StringBuffer的区别?5、如何理解面向对象和面向过程&…

浅谈叉车车载电脑的市场现状

叉车的起源 叉车源于美国,兴于日本,虽然中国起步较晚,但是近些年来发展迅速。叉车又称叉式装载车,是对于成件托盘类货物进行装卸、堆垛和短距离运输,实现重物搬运作业的轮式工业车辆。 叉车的分类 叉车分为以上六大类…

CSS学习(选择器、盒子模型)

1、CSS了解 CSS:层叠样式表,一种标记语言,用于给HTML结构设置样式。 样式:文字大小、背景颜色等 p标签内不能嵌套标题标签。 px是相对于分辨率而言的, em是相对于浏览器的默认字体, rem是相对于HTML根元…

刷题日记 ---- 顺序表与链表相关经典算法题(C语言版)

目录 1. 移除元素2. 合并两个有序数组3. 移除链表元素4. 反转链表5. 合并两个有序链表6. 链表的中间结点7. 环形链表的约瑟夫问题8. 分割链表总结 正文开始 1. 移除元素 题目链接: 移除元素 题目描述: 思路历程: 题目明确要求, 不能使用额外的数组空间, 也就是说不可以创建…

【优质书籍推荐】AIGC时代的PyTorch 深度学习与企业级项目实战

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…

springcloud按版本发布微服务达到不停机更新的效果

本文基于以下环境完成 spring-boot 2.3.2.RELEASEspring-cloud Hoxton.SR9spring-cloud-alibaba 2.2.6.RELEASEspring-cloud-starter-gateway 2.2.6.RELEASEspring-cloud-starter-loadbalancer 2.2.6.RELEASEnacos 2.0.3 一、思路 实现思路: 前端项目在请求后端接…

C++ 哈希

💓博主CSDN主页:麻辣韭菜💓   ⏩专栏分类:C知识分享⏪   🚚代码仓库:C高阶🚚   🌹关注我🫵带你学习更多C知识   🔝🔝 ​ 前言 1. unordered系列关联式容器 1.1 unor…

必应bing国内广告开户注册教程!

今天搜索引擎广告成为企业推广产品与服务、提升品牌知名度的重要渠道之一。作为全球第二大搜索引擎,必应Bing凭借其高质量的用户群体和广泛的国际覆盖,为广告主提供了独特的市场机遇。在中国,虽然必应的市场份额相对较小,但对于寻…

磁密固定下的三次谐波与电压谐波的关系

同相位或者相位差为180的情况下,磁通密度三次谐波含量占比 α \alpha α,则电压三次谐波含量占比为 3 α 3\alpha 3α 同相位,磁通密度三次谐波含量占比 α \alpha α情况下, B B 0 sin ⁡ ( ω t ) α B 0 sin ⁡ ( 3 ω t )…

航空企业数字化解决方案(207页PPT)

一、资料描述 航空企业数字化解决方案是一项针对航空公司在数字化转型过程中所面临挑战的全面应对策略,旨在通过先进的信息技术提升航空企业的运营效率、客户服务水平以及市场竞争力。这份207页的PPT详细介绍了航空企业数字化的各个方面,包括关键技术的…

Web3技术解析:区块链在去中心化应用中的角色

引言 在过去几年中,Web3技术已经成为了互联网领域的一个热门话题。作为区块链技术的延伸,Web3不仅仅是数字货币的代名词,更是一个能够为各种应用提供去中心化解决方案的强大工具。本文将深入探讨区块链在Web3去中心化应用中的关键角色&#…

ubuntu查看opencveigen

ubuntu查看opencv&eigen&cmake版本的方法 eigen eigen版本号在/usr/include/eigen3/Eigen/src/Core/util/Macros.h文件中,下图代表版本3.3.7 opencv版本 pkg-config --modversion opencv4也可能最后的字符串是opencv2,opencv

W801学习笔记十二:掌机进阶V3版本之驱动(PSRAM/SD卡)

本次升级添加了两个模块,现在要把他们驱动起来。 一:PSRAM 使用SDK自带的驱动,我们只需要写一个初始化函数,并在其中添加一些自检代码。 void psram_heap_init(){wm_psram_config(0);//实际使用的psram管脚选择0或者1&#xff…

Java学习路线及自我规划

荒废了一段时间,这段时间的总结开始了JavaWeb的学习但是困难重重,例如Maven,Vue的路由等,所以我反省了一段时间,因为基础薄弱,加之学习的资源是速成视频,导致大厦将倾的局面(也算不上…

RabbitMQ工作模式(5) - 主题模式

概念 主题模式(Topic Exchange)是 RabbitMQ 中一种灵活且强大的消息传递模式,它允许生产者根据消息的特定属性将消息发送到一个交换机,并且消费者可以根据自己的需求来接收感兴趣的消息。主题交换机根据消息的路由键和绑定队列的路…

盲人地图使用的革新体验:助力视障人士独立、安全出行

在我们日常生活中,地图导航已经成为不可或缺的出行工具。而对于盲人群体来说,盲人地图使用这一课题的重要性不言而喻,它不仅关乎他们的出行便利性,更是他们追求生活独立与品质的重要一环。 近年来,一款名为蝙蝠…