Java:线程的六种状态及转化
目录
前文传送门:多线程概述及创建方式
Java:线程的六种状态及转化
关于线程的生命周期,网上书上说法不一,难以统一,本篇做一个总结:
java.lang.Thread.State枚举类中定义了六种线程的状态,可以调用线程Thread中的getState()方法获取当前线程的状态。
| 线程状态 | 解释 |
|---|---|
| NEW | 尚未启动的线程状态,即线程创建,还未调用start方法 |
| RUNNABLE | 就绪状态(调用start,等待调度)+正在运行 |
| BLOCKED | 等待监视器锁时,陷入阻塞状态 |
| WAITING | 等待状态的线程正在等待另一线程执行特定的操作(如notify) |
| TIMED_WAITING | 具有指定等待时间的等待状态 |
| TERMINATED | 线程完成执行,终止状态 |
下图源自《Java并发编程艺术》图4-1

一、新建状态(NEW)
即用new关键字新建一个线程,这个线程就处于新建状态。
二、运行状态(RUNNABLE)
操作系统中的就绪和运行两种状态,在Java中统称为RUNNABLE。
就绪状态(READY)
当线程对象调用了start()方法之后,线程处于就绪状态,就绪意味着该线程可以执行,但具体啥时候执行将取决于JVM里线程调度器的调度。
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
不允许对一个线程多次使用start。
线程执行完成之后,不能试图用start将其唤醒。
其他状态 ->就绪
- 线程调用start(),新建状态转化为就绪状态。
- 线程sleep(long)时间到,等待状态转化为就绪状态。
- 阻塞式IO操作结果返回,线程变为就绪状态。
- 其他线程调用join()方法,结束之后转化为就绪状态。
- 线程对象拿到对象锁之后,也会进入就绪状态。
运行状态(RUNNING)
处于就绪状态的线程获得了CPU之后,真正开始执行run()方法的线程执行体时,意味着该线程就已经处于运行状态。需要注意的是,对于单处理器,一个时刻只能有一个线程处于运行状态。
对于抢占式策略的系统来说,系统会给每个线程一小段时间处理各自的任务。时间用完之后,系统负责夺回线程占用的资源。下一段时间里,系统会根据一定规则,再次进行调度。
运行状态转变为就绪状态的情形:
- 线程失去处理器资源。线程不一定完整执行的,执行到一半,说不定就被别的线程抢走了。
- 调用yield()静态方法,暂时暂停当前线程,让系统的线程调度器重新调度一次,它自己完全有可能再次运行。
yield方法的官方解释:
A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore this hint.
提示调度程序,当前线程愿意放弃当前对处理器的使用。这时,当前线程将会被置为就绪状态,和其他线程一样等待调度,这时候根据不同优先级决定的概率,当前线程完全有可能再次抢到处理器资源。
三、阻塞状态(BLOCKED)
阻塞状态表示线程正等待监视器锁,而陷入的状态。
以下场景线程将会阻塞:
- 线程等待进入synchronized同步方法。
- 线程等待进入synchronized同步代码块。
线程取得锁,就会从阻塞状态转变为就绪状态。
四、等待状态(WAITING)
进入该状态表示当前线程需要等待其他线程做出一些的特定的动作(通知或中断)。
运行->等待
- 当前线程运行过程中,其他线程调用
join方法,当前线程将会进入等待状态。 - 当前线程对象调用
wait()方法。
-LockSupport.park():出于线程调度的目的禁用当前线程。
等待->就绪
- 等待的线程被其他线程对象唤醒,
notify()和notifyAll()。 LockSupport.unpark(Thread),与上面park方法对应,给出许可证,解除等待状态。
五、超时等待状态(TIMED_WAITING)
区别于WAITING,它可以在指定的时间自行返回。
运行->超时等待
- 调用静态方法,
Thread.sleep(long) - 线程对象调用
wait(long)方法 - 其他线程调用指定时间的
join(long)。 LockSupport.parkNanos()。LockSupport.parkUntil()。
补充:
sleep和yield的不同之处:
- sleep(long)方法会使线程转入超时等待状态,时间到了之后才会转入就绪状态。而yield()方法不会将线程转入等待,而是强制线程进入就绪状态。
- 使用sleep(long)方法需要处理异常,而yield()不用。
超时等待->就绪
- 同样的,等待的线程被其他线程对象唤醒,
notify()和notifyAll()。 LockSupport.unpark(Thread)。
六、消亡状态
即线程的终止,表示线程已经执行完毕。前面已经说了,已经消亡的线程不能通过start再次唤醒。
- run()和call()线程执行体中顺利执行完毕,线程正常终止。
- 线程抛出一个没有捕获的Exception或Error。
需要注意的是:主线成和子线程互不影响,子线程并不会因为主线程结束就结束。
许多地方仍需后期补充,敬请期待。
参考资料:《JAVA并发编程实践》、《疯狂Java讲义》、《Java并发编程艺术》
Java:线程的六种状态及转化的更多相关文章
- Java线程的六种状态
java线程有很多种状态,最主要的有六种,被创建.运行.睡眠.等待.阻塞以及消亡六种,也有很多归结为5种,把睡眠以及等待归结为冻结: 被创建:就是线程被创建,就是new thread()之后就是创建一 ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- java线程五种状态
java线程五种状态: 创建 -> 就绪 -> 运行 -> 销毁 创建 -> 就绪 -> 运行 -> 等待(缺少资源) -> 销毁 下图:各种状态转换
- java线程四种状态
一个线程可以有四种状态: 1.新(new), 即线程刚刚创建,而并未执行 2.可运行(runnable),意味着一旦时间分片机制有空闲的CPU周期提供给一个线程,那个线程便可立即开始运行.因此,线程可 ...
- 为什么 Java 线程没有 Running 状态?
Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事.具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么 ...
- java线程的五大状态,阻塞状态详解
一.状态简介 一个线程的生命周期里有五大状态,分别是: 新生 就绪 运行 死亡 运行后可能遇到的阻塞状态 二.相关方法 2.1 新生状态 Thread t = new Thread(); 正如我们前面 ...
- JAVA线程间的状态转换
线程间的状态转换: 1. 新建(new):新创建了一个线程对象. 2. 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法.该状态的线程位于可运 ...
- Java-技术专区-如何监控Java线程池的状态
线程池介绍 什么是线程池.线程池核心类.线程池工作流程.线程池分类.拒绝策略.及如何提交与关闭线程池等. 但在实际开发过程中,在线程池使用过程中可能会遇到各方面的故障,如线程池阻塞,无法提交新任务等. ...
- java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue
在有些严格的系统中,我们需要做到干净的停止线程并清理相关状态.涉及到这个主题会带出很多的相关点,简单的总结如下: 我们知道,在java中,有一个volatile关键字,其官方说明(https://do ...
随机推荐
- 001 Ceph简介
一.Ceph简介 Red Hat Ceph是一个分布式的数据对象存储,系统设计旨在性能.可靠性和可扩展性上能够提供优秀的存储服务.Ceph分布式存储能够在一个统一的系统中同时提供了对象.块.和文件存储 ...
- 闯荡Linux帝国:nginx的创业故事
前情回顾: NextStep帝国推出的web服务,迅速风靡比特宇宙,各星系帝国均蠢蠢欲动,想在这一波浪潮中掘一桶金. 详情参见:万维网的诞生 初出茅庐 小马哥和他的小伙伴小黑.大黄来到陌生的Linux ...
- C# 为什么说事件是一种特殊的委托
很多人说C#的事件是一种特殊的委托,其实并不是,这是对事件的一种误解 C# 事件模型的五个组成部分 1.事件的拥有者 2.事件成员(事件的本身) 3.事件响应者 4.事件处理器:本质上是一种回调方法 ...
- Mybatis 学习过程中出现空指针异常的错误【已解决】
Mybatis 学习过程中出现空指针异常的错误[已解决] 以下是写的小测试的代码 bean层 Player类(篮球队队员) bean层 Team类(篮球队) dao层 TeamDao.xml配置文件 ...
- 「洛谷P3469」[POI2008]BLO-Blockade 解题报告
P3469[POI2008]LO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每两个 ...
- mysql报错1548-Cannot load from mysql.proc. The table is probably corrupted
我的版本是5.5.53, 进入到MYSQL-front后,一点击localhost就报错 网上的例子都是说使用mysql_upgrade更新 但是我的是在phpstudy里的mysql,并没有mysq ...
- 高效测试框架推荐之Ginkgo
自2015年开始,七牛工效团队一直使用Go语言+Ginkgo的组合来编写自动化测试用例,积累了大约5000+的数量.在使用和维护过程中,我们觉得Ginkgo的很多设计理念和功能非常赞,因此特分享给大家 ...
- 大白话原型模式(Prototype Pattern)
意图 原型模式是创建型设计模式,可以复制已存在的对象而无需依赖它的类. 问题 假如现在有一个对象,我们想完全复制一份新的,我们该如何做? 创建同一个类的新对象 遍历所有已存在对象的值,然后将他们的值复 ...
- 解析Json字符串中的指定的值
{ "head": { ", "Id": "20191008144448iAQE", "Message": & ...
- spark storm 反压
因特殊业务场景,如大促.秒杀活动与突发热点事情等业务流量在短时间内剧增,形成巨大的流量毛刺,数据流入的速度远高于数据处理的速度,对流处理系统构成巨大的负载压力,如果不能正确处理,可能导致集群资源耗尽最 ...