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 ...
随机推荐
- Zabbix监控web
1.1 创建主机 1.2 应用集 1.3 创建web场景 1.4 创建触发器
- Python学习3月8号【python编程 从入门到实践】---》笔记(1)
第十章:处理文件和异常 #学习处理文件,让程序能够快速地分析大量的数据#学习错误处理,避免程序在面对意外情形时崩溃#学习异常,是python创建的特殊对象,用于管理程序运行时出现#学习模块json,它 ...
- 006一句话解决主机pc,Vmware虚拟机,开发板之间的ping问题
- linux solr7.2+tomcat8 详细部署整合
1.去solr官网下solr-7.2.0.tgz 2.上传至linux解压 tar -zxvf solr-7.2.0.tgz 3.准备tomcat8 拷贝solr-7.2.0/server/solr- ...
- Git 连接github
大概如下: 详细如下:如果使用本文命令,请仔细选择,因为添加一些相关命令以供参考. 1 本地仓库 1.1 创建git 仓库 git init # 初始化本地仓库 git --version # 查看G ...
- 1023 组个最小数 (20 分)C语言
给定数字 0-9 各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 5,一个 8,我们得到的最小的数就 ...
- virtualenv虚拟环境使用及介绍
一.为什么使用virtualenv虚拟环境 每个虚拟环境下的依赖相互独立,不同的项目可以单独使用一套python环境,减少各依赖包的影响 更容易部署 容器化 二.virtualenv创建虚拟环境 三. ...
- .net core 开车记:Data Protection Key 过期问题与登录页面访问慢
K8s 船还没修好,.net core 车又出了问题,开着 k8s 豪华邮轮.飚着 .net core 极品飞车的好事真是多磨. 自从我们用上 .net core ,就一直被 .net core 的一 ...
- Arrays.asList 返回值类型
public static void main(String[] args) { Integer[] datas = {1,2,3,4,5}; List<Integer> list = A ...
- POJ 1269 Intersecting Lines(判断两直线位置关系)
题目传送门:POJ 1269 Intersecting Lines Description We all know that a pair of distinct points on a plane ...