Java中线程的状态

Java中线程的状态分为6种。

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

这6种状态定义在Thread类的State枚举中,可查看源码进行一一对应。

一、线程的状态图
在这里插入图片描述

二、状态详细说明

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

2.1. 就绪状态(RUNNABLE之READY)
就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
调用线程的start()方法,此线程进入就绪状态。
当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
锁池里的线程拿到对象锁后,进入就绪状态。
2.2. 运行中状态(RUNNABLE之RUNNING)
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一的一种方式。

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

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

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

  4. 终止状态(TERMINATED)
    当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
    在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
    三、等待队列
    调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。
    与等待队列相关的步骤和图

线程1获取对象A的锁,正在使用对象A。
线程1调用对象A的wait()方法。
线程1释放对象A的锁,并马上进入等待队列。
锁池里面的对象争抢对象A的锁。
线程5获得对象A的锁,进入synchronized块,使用对象A。
线程5调用对象A的notifyAll()方法,唤醒所有线程,所有线程进入同步队列。若线程5调用对象A的notify()方法,则唤醒一个线程,不知道会唤醒谁,被唤醒的那个线程进入同步队列。
notifyAll()方法所在synchronized结束,线程5释放对象A的锁。
同步队列的线程争抢对象锁,但线程1什么时候能抢到就不知道了。
四、同步队列状态
当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入同步队列。简言之,同步队列里面放的都是想争夺对象锁的线程。
当一个线程1被另外一个线程2唤醒时,1线程进入同步队列,去争夺对象锁。
同步队列是在同步的环境下才有的概念,一个对象对应一个同步队列。
线程等待时间到了或被notify/notifyAll唤醒后,会进入同步队列竞争锁,如果获得锁,进入RUNNABLE状态,否则进入BLOCKED状态等待获取锁。
五、几个方法的比较
Thread.sleep(long millis),一定是当前线程调用此方法,当前线程进入TIMED_WAITING状态,但不释放对象锁,millis后线程自动苏醒进入就绪状态。作用:给其它线程执行机会的最佳方式。
Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的CPU时间片,但不释放锁资源,由运行状态变为就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。
thread.join()/thread.join(long millis),当前线程里调用其它线程t的join方法,当前线程进入WAITING/TIMED_WAITING状态,当前线程不会释放已经持有的对象锁。线程t执行完毕或者millis时间到,当前线程一般情况下进入RUNNABLE状态,也有可能进入BLOCKED状态(因为join是基于wait实现的)。
obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout) timeout时间到自动唤醒。
obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。
LockSupport.park()/LockSupport.parkNanos(long nanos),LockSupport.parkUntil(long deadlines), 当前线程进入WAITING/TIMED_WAITING状态。对比wait方法,不需要获得锁就可以让线程进入WAITING/TIMED_WAITING状态,需要通过LockSupport.unpark(Thread thread)唤醒。
六、疑问
等待队列里许许多多的线程都wait()在一个对象上,此时某一线程调用了对象的notify()方法,那唤醒的到底是哪个线程?随机?队列FIFO?or sth else?Java文档就简单的写了句:选择是任意性的(The choice is arbitrary and occurs at the discretion of the implementation)。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gateway的使用

什么是Spring Cloud Gateway 网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。相比 Zuul 来说,Spring Cloud …

ADV7391BCPZ-ASEMI代理亚德诺ADV7391BCPZ原厂芯片

编辑-Z ADV7391BCPZ参数描述: 型号:ADV7391BCPZ VDD:1.8V VAA:3.3V 全驱动输出电流:34.6 mA 低驱动输出电流:4.3 mA 输出电容:10 pF 模拟输出延迟:6 ns DAC模拟输出倾斜&am…

文件一直处于修改状态 git checkout 无法还原的问题解决方法

问题描述 最近在 RT-Thread 时,使用 Git 回退版本验证问题,后来 git pull 拉取最新代码后,发现里面有几个文件,一直为【修改】状态,并且无法还原,git checkout xxx git reset --hard 都用了,依旧…

简单两步创建nVisual建筑场景

nVisual是一款网络基础设施可视化管理软件,通过模型可规划即将建设的机房效果,或者将已有的机房场景复刻至系统中,便于运维管理者清晰的了解机房设备及线缆路由连接关系。 数据初始我们需要将数据中心场景复刻至系统中,建筑场景也…

【Java】抽象类与接口

文章目录 1.抽象类1.1抽象方法 2.接口3.抽象类和接口的区别3.1代码中区分:3.2设计层面区分 在面向对象编程中,抽象是非常重要的一个特征。在Java中可以通过抽象类或接口的形式实现这一特性。 1.抽象类 Java关键字 abstract对应抽象类的使用 1.1抽象方法…

Calico的BGP打通Kubernetes网络和局域网

1、项目背景 随着云原生技术的不断发展,容器化应用已成为企业构建云原生架构的重要方式。而随着集群规模不断扩大,跨主机通信的需求也越来越重要。在 Kubernetes 集群中,Pod 是最小的调度和管理单位,而网络也是 Kubernetes 中最重…

二叉树OJ

文章目录 二叉树OJ根据二叉树创建字符串思路示例代码 二叉树的层序遍历思路示例代码 二叉树的层序遍历 II思路示例代码 二叉树的最近公共祖先思路1示例代码1思路2示例代码2 二叉搜索树与双向链表思路1示例代码1思路2示例代码2 迭代实现二叉树的三种遍历前序遍历思路示例代码 中…

哪些蓝牙耳机戴久不疼?长时间佩戴不疼的蓝牙耳机推荐

现在的真无线耳机已经成为了人们的标配之一了,各个厂家也紧随其后,生产出了多种无线耳机,不少人的选购蓝牙耳机一般都是对音质、佩戴和连接,但通常人们佩戴蓝牙耳机都是在半天左右,小编专门整理了一期舒适度高的耳机&a…

ElasticSeach 集成 springboot

声明是ElasticSearch? ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎, 基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是 当前流行的企业级搜索引擎…

Unity 坐标系

一、左手坐标系与右手坐标系 常见的三维软件都采用笛卡尔坐标系,也就是常见的xyz轴坐标系。笛卡尔坐标系可以是左手坐标系也可以是右手坐标系,如下图所示 两种坐标系是镜像对称的。而Unity采用左手系,且xyz轴的默认方向与图中的左手系完全一…

便携式车用CAN分析仪

产品简介 USBCAN-C系列便携式车用CAN分析仪,通过USB接口快速扩展一路CAN通道,使接入CAN网络非常容易,它具有一体式和小巧紧凑的外形,特别适合于随身携带。CAN接口采用金升阳电源模块和信号隔离芯片实现2500V DC电气隔离&#xff0…

KVM存储池管理与磁盘格式

KVM存储池管理与磁盘格式 KVM必须配置一个目录作为存储磁盘镜像(存储卷)的目录,我们称这个目录为存储池 存储池管理 默认存储池 /var/lib/libvirt/images/ 创建基于文件夹的存储池(目录) mkdir -p /data/vmfs定义…

WhatsApp如何让客户参与变得更简单?

WhatsApp对你的品牌来说可能和Twitter和Facebook一样重要,你可能已经把它们纳入你的社交媒体战略。 是的,WhatsApp不仅仅可以用来给同事发短信或与远方的亲戚视频聊天,它也适用于商业。 在发展WhatsApp业务时,小企业主得到了最优…

【网络】Socket编程-UDP篇

文章目录 预备知识源IP地址和目的IP地址源MAC地址和目的MAC地址源端口号和目的端口号"端口号port" 和 "进程ID"认识TCP/UDP协议网络字节序 Socket编程sockaddr结构API接口 简单的UDP网络程序服务器server服务端创建套接字:socket函数**socket的底层原理** …

Unity学习笔记 关于Unity相机的FOV以及水平FOV和垂直FOV之间的转换

前言 关于FOV FOV 是在任何给定时间通过人眼、相机取景器或在显示屏上可见的可观察世界的范围。它指的是整个区域的覆盖范围,而不是单个固定焦点。FOV 还描述了一个人可以看到可见世界的角度。 FOV 越宽,可以看到的可观察世界就越多。它是水平、垂直和对…

使用 OpenCV 进行基于 ESP32 CAM 的目标检测和识别

概述:基于 ESP32 CAM 的目标检测和识别 本教程介绍了使用OpenCV基于 ESP32 CAM的目标检测和识别主题。OpenCV 是一个开源的图像处理库,不仅在工业界而且在研发领域都得到了非常广泛的应用。 这里对于对象检测,我们使用了cvlib 库。该库使用 COCO 数据集上的预训练 AI 模型…

JSON-框架的具体使用

JSON-框架的具体使用 非 SpringBoot 项目 Jackson Jackson 是另一个流行的JSON序列化和反序列化库,具有以下特点 速度快:Jackson 采用了高效的JSON解析算法和字节码生成技术,使得其序列化和反序列化速度非常快。支持全类型序列化&#xff1…

4年外包终于上岸,我只能说别去....

我大学学的是计算机专业,毕业的时候,对于找工作比较迷茫,也不知道当时怎么想的,一头就扎进了一家外包公司,一干就是4年。现在终于跳槽到了互联网公司了,我想说的是,但凡有点机会,千万…

C语言-【移位操作符详解】

这篇文章主要介绍了C语言中移位操作符,文章中通过详细的代码以及有关计算机中零碎的知识点对移位操作符进行了一个更好的解释,需要的小伙伴们可以一起学习学习吖~ 移位操作符:移动的是补码的二进制序列。 在C语言当中,有两种移位…

「OceanBase 4.1 体验」|OCP Express

文章目录 一、简介二、特性介绍2.1 数据库管理2.2 数据库可观测性 一、简介 OCP Express 是一个基于 Web 的 OceanBase 4.x 轻量化管理工具,作为 OceanBase 数据库的工具组件,它集成在 OceanBase 数据库集群中,支持数据库集群关键性能指标查看…