线程状态是五种对?还是六种对?

2023-11-04

五种:

线程在一定条件下,状态会发生变化。线程一共有以下几种状态:

1、新建状态(New):新创建了一个线程对象。

2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权,

   即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

   阻塞的情况分三种:

①.等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,

   必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

②.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

③.其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时,

   或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

   线程变化的状态转换图如下:

PS:拿到对象的锁标记,即为获得了对该对象(临界区)的使用权限。即该线程获得了运行所需的资源,进入“就绪状态”,只需获得CPU,就可以运行。

    因为当调用wait()后,线程会释放掉它所占有的“锁标志”,所以线程只有在此获取资源才能进入就绪状态。

下面作下解释: 

①.线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,  当我们new了这个对象后,线程就进入了初始状态; 

②.当该对象调用了start()方法,就进入就绪状态; 

③.进入就绪后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态; 

④.进入运行状态后情况就比较复杂;

   (1)run()方法或main()方法结束后,线程就进入终止状态; 

   (2)当线程调用了自身的sleep()方法或其他线程的join()方法,进程让出CPU,然后就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源,

       即调用sleep()函数后,线程不会释放它的“锁标志”。)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配CPU时间片;

       典型地,sleep()被用在等待某个资源就绪的情形;测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。

   (3)线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到就绪状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态;

       调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间片从而需要转到另一个线程。yield()只是使当前线程重新回到可执行状态,

       所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

   (4)当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记

      (这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入就绪状态,等待OS分配CPU时间片。

   (5)suspend() 和 resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。

       典型地,suspend()和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用resume()使其恢复。 

   (6)wait()和 notify() 方法:当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,

       必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,

       因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。 

       wait() 使得线程进入阻塞状态,它有两种形式:

       一种允许指定以ms为单位的时间作为参数,另一种没有参数。前者当对应的notify()被调用或超出指定时间时线程重新进入可执行状态即就绪状态,后者则必须对应的notify()被调用。

       当调用wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。

       waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronizedblock中进行调用。

       如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

六种:

NEW:线程被创建出来了,但是还没有start()。

RUNNABLE:可运行状态,这个状态比较特殊,我在图中把这个状态拆分成了两部分:一部分是READY,顾名思义是准备状态,另一部分是RUNNING,即运行状态。

准备状态:只能说明你有资格运行,单只要调度程序没有调度到你,你就永远是准备状态。从图中可以看出,好几个状态都能切换到准备状态,至于切换的方法,我在下文详细给大家整理出来介绍。

运行状态:线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。说白了,就是线程跑起来了。

BLOCKED:阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。

WAITING:等待状态的线程不会被分配 CPU 执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。

TIMED_WAITING:超时等待状态的线程不会被分配 CPU 执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。这是和上面的 WAITING 状态的区别。

TERMINATED:终止状态,顾名思义,线程执行结束了。

为什么会有五种和六种的说法呢,其实,实际上,两种都算是对的,只不过,线程有六种状态更贴近官方的说法,更为合适一些。以上仅是个人看法,如有不同意见,欢迎评论区交流沟通

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

线程状态是五种对?还是六种对? 的相关文章

  • Java 中等效的并行扩展

    我在 Net 开发中使用并行扩展有一些经验 但我正在考虑在 Java 中做一些工作 这些工作将受益于易于使用的并行库 JVM 是否提供任何与并行扩展类似的工具 您应该熟悉java util concurrent http java sun
  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • Java按日期升序对列表对象进行排序[重复]

    这个问题在这里已经有答案了 我想按一个参数对对象列表进行排序 其日期格式为 YYYY MM DD HH mm 按升序排列 我找不到正确的解决方案 在 python 中使用 lambda 很容易对其进行排序 但在 Java 中我遇到了问题 f
  • 如何将 pfx 文件转换为 jks,然后通过使用 wsdl 生成的类来使用它来签署传出的肥皂请求

    我正在寻找一个代码示例 该示例演示如何使用 PFX 证书通过 SSL 访问安全 Web 服务 我有证书及其密码 我首先使用下面提到的命令创建一个 KeyStore 实例 keytool importkeystore destkeystore
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 使用 JMF 创建 RTP 流时出现问题

    我正处于一个项目的早期阶段 需要使用 RTP 广播DataStream创建自MediaLocation 我正在遵循一些示例代码 该代码目前在rptManager initalize localAddress 出现错误 无法打开本地数据端口
  • java.lang.IllegalStateException:驱动程序可执行文件的路径必须由 webdriver.chrome.driver 系统属性设置 - Similiar 不回答

    尝试学习 Selenium 我打开了类似的问题 但似乎没有任何帮助 我的代码 package seleniumPractice import org openqa selenium WebDriver import org openqa s
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • 统计学基础-数据的图表展示

    理论基础 什么是统计学 统计学分为描述统计和推理统计 统计学研究什么 统计学没有固定的研究对象 统计学研究的是来自各个领域的数据 靠解决其他领域内的工作而生存 我们并不能因此就看轻统计学 就好像计算机现在渗透在各行各业 我们生活中的方方面面
  • iOS支付宝支付接入的几个坑—以及解决办法

    因为近期项目中需要接入支付宝支付功能 自己也爬了很多的坑 所以做了一下这边文章供大家学习参考 远离爬坑 文章主要讲到以下五部分 一 支付宝开放平台创建应用 二 签约移动支付功能 三 接入支付前的准备工作附准备工作中遇到难题的解决方法 四 配
  • window.open打开新窗口报错ie 位指明错误,原因是window没有加引号!

    function JsMod htmlurl tmpWidth tmpHeight htmlurl getRandomUrl htmlurl var newwin window open htmlurl window height tmpH
  • VUE前端框架

    目录 vue 概述 MVVM框架 入门案例 创建HTML文件 并引入vue js 练习 Vue的基础语法 1 运算符 函数 2 解析类型丰富的data 3 data的三种写法 二 Vue的指令 1 概述 2 v model v cloak
  • Download-centos7-repo

    Setup Local Yum Repository On CentOS 7 使用ftp和createrepo来构建iso中的rpm包源 install and cache rpm package cat etc yum conf more
  • 【网络结构设计】6、CSPNet

    文章目录 一 背景 二 方法 2 1 DenseNet 网络结构 2 2 Cross Stage Partial DenseNet 2 3 将 CSPNet 和其他结构结合 三 效果 论文 CSPNet A new backbone tha
  • 数据库相关中间件收录集

    数据库中间件 这里主要介绍互联网行业内有关数据库的相关中间件 数据库相关平台主要解决以下三个方面的问题 为海量前台数据提供高性能 大容量 高可用性的访问 为数据变更的消费提供准实时的保障 高效的异地数据同步 应用层通过分表分库中间件访问数据
  • ajaxForm和ajaxSubmit

    ajaxForm和ajaxSubmit 1 AjaxForm ajaxForm不能提交表单 在document的ready函数中 使用ajaxForm来为AJAX提交表单进行准备 提交动作必须由submit开始 document ready
  • java kafka关闭连接_kafka的连接问题,我如何通过代码知道服务端的kafka服务是否开启?...

    我在电脑的虚拟机搭建了kafka服务 在本地使用Java客户端进行访问 现在假如虚拟机上的服务被我关闭 我在本地的代码就会无法去向kafka推送消息 并且会在1分钟后报一个timeout的错 我可以控制这个timeout的时间吗 我应该怎么
  • 域名与IP地址的联系与区别

    转载自一个好朋友的博客链接 略有修改 共同学习 共同进步 我们也知道每一台机都有一个唯一ip地址 特别难记 所以出现了今天的DNS 域名 当我们的计算机想要和一个远程机器连接时 我们可以申请连接该机器ip地址下的DNS 例如 www bai
  • STM32应用开发实践教程:基于 RS-485 总线的多机通信应用开发

    5 1 1 任务分析 本任务要求设计一个基于 RS 485 总线的多机通信系统 系统中有两台设备 理论上最多可 接入 32 台设备 其中一台设备作为主机 连接 OLED 显示屏 另一台设备作为从机 连接温 湿度传感器 DHT11 与 LED
  • Centos 7安装部署PostgreSql 12

    安装 yum install https download postgresql org pub repos yum reporpms EL 8 x86 64 pgdg redhat repo latest noarch rpm yum i
  • 装饰器原理

    原理 原有函数 def fun 1 正常调用原有函数 fun 1 现有需要需要在原有函数基础上添加新功能 但是不改变原有函数法一 1 添加新函数 装饰一波 def fun 2 fun 1 嵌套函数 返回函数地址 fun 3 调用时才执行 d
  • Java数组全排列

    递归法 当数组元素重复时 会出现重复排列 public static void main String args int arr new int 1 2 3 4 5 6 7 8 9 f arr 0 static void f int arr
  • 聊聊Qt中的Widget调色板QPalette

    在实际的应用开发中 经常需要对某个窗体或某个控件的颜色外观 如背景色 前景色等进行设置 已达到界面美化的效果 Qt中的窗体或控件都是Widget类 Qt中提供的调色板QPalette类就是专门用于管理控件的外观显示 QPalette类相当于
  • bert模型蒸馏实战

    由于bert模型参数很大 在用到生产环境中推理效率难以满足要求 因此经常需要将模型进行压缩 常用的模型压缩的方法有剪枝 蒸馏和量化等方法 比较容易实现的方法为知识蒸馏 下面便介绍如何将bert模型进行蒸馏 一 知识蒸馏原理 模型蒸馏的目的是
  • 计算机的配件知识,组装一台电脑需要哪些配件 DIY装机必看的电脑硬件知识详解 (全文)...

    组装电脑是指用户可以按照自己的预算和用途来 在兼容的基础上 灵活搭配电脑硬件 又称为DIY组装电脑 DIY攒机等 由于灵活 高性价比 按需搭配等特性 是不少台式电脑主流方案之选 那么组装一台电脑需要哪些配件 下面 电脑爱好者 分享一下DIY
  • MinIO 对象存储(可以当作免费的图床)

    什么是Minlo MinIO与传统的存储和其他的对象存储不同的是 特征 一 快速入门 1 下载直接去官网 2 新建minio安装目录 执行如下命令 3 后台启动 4 查看状态 二 进行访问 并设置桶 1 访问 三 springboot进行实
  • Java中类数组,创建后使用set函数,报NullPointerException空指针异常

    最近从新学习数组发现了一些问题 先创建一个Person类 public class Person private String name private int age public Person String name int age t
  • 线程状态是五种对?还是六种对?

    五种 线程在一定条件下 状态会发生变化 线程一共有以下几种状态 1 新建状态 New 新创建了一个线程对象 2 就绪状态 Runnable 线程对象创建后 其他线程调用了该对象的start 方法 该状态的线程位于 可运行线程池 中 变得可运