深入玩转JAVA多线程 Thread状态与生命周期
Posted 开普勒鑫球
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入玩转JAVA多线程 Thread状态与生命周期相关的知识,希望对你有一定的参考价值。
作者|开鑫金服-东东(DingXD)
编辑|Andy
Thread状态与生命周期
问题:
一个thread在start执行完后,还能再次start吗?
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.start();
连续调用两次start会异常
Exception in thread "main" java.lang.IllegalThreadStateException
原因是thread是有状态的,且有些状态之间的切换是不可逆的
Thread的状态
1、新建状态(New):新创建一个线程对象的初始状态。
2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于JVM可运行线程池中,变得可运行。该状态下线程等待操作系统调度,获取CPU的使用权后就可以执行线程代码。
3、阻塞状态(BLOCKED):线程在执行过程中,遇到被synchronized关键字保护的代码,等待获得被保护对象的锁(waiting for a monitor lock),此时线程会停止执行。
注意:只有synchronized这种方式的锁(monitor锁)才会让线程进入BLOCKED状态,等待利用cas实现的锁(如ReentrantLock)时,线程仍然处于Runnable状态。
4、等待状态(WAITING or TIMED_WAITING):
让线程进入WAITING只有一种方式:在同步块中,调用锁对象的wait方法,也会让当前持有锁的线程进入wait状态。
public static void timedWaiting() {
final Object lock = new Object();
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
}
让线程进入TIMED_WAITING状态,可以给wait方法加一个入参超时时间,或者直接调用线程的thread.join()方法。
处于WAITING状态的线程,只有其他线程调用了锁对象的notify方法才会执行。
处于TIMED_WAITING的线程,除了被锁对象的notify方法唤醒外,到了超时时间会自动唤醒(被join方法阻塞的线程不会被自动唤醒,因为在底层实现中超时时间被设置为0)。
5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
其实从字面意思就可以看出来:
blocked是过去分词,意思是线程在执行过程中被别人卡住了,即其他线程正在执行这段由synchd保护的代码,等别人执行完自己就会自动执行(jvm调度控制),不需要其他线程唤醒。
而waiting是主动执行wait动作后的当前状态,是主动卡住自己,必须由其他线程调用notify方法才能唤醒。
从下面代码可以方便的理解:
假设t1,t2先后两个线程,都执行如下代码:
synchronized(Obj) {
Obj.wait();
}
t1先进,最后在Obj.wait()下卡住,这时java管t1的状态waitting状态
t2后进,直接在第一行就卡住了,这时java叫t2为blocked状态。
Java处于方便管理的考虑,将blocked和waiting状态的线程放到两个队列里(BlockSet和WaitSet),当别的线程运行出了synchronized这段代码,jvm只需要去BlockSet里取,当某人调用了notify(),jvm只需要从WaitSet里取,后面锁机制的章节会详细介绍。
所以两个状态的本质区别是进入和唤醒的条件不一样,其他没有任何区别。
Thread生命周期
参考国外网站上一张图,个人认为画的最详细
注意:
1、 Waiting、Block、Runnable之间可以两两切换,而TERMINATED就是终态了,永远不可能在启动了。
2、 处于Runnable状态的线程,并不是立马就执行了,而是等待操作系统的调度启动。且线程再被CPU执行时也不是一口气执行到期,操作系统可能会将线程调出(比如有更高优先级的线程要处理),后续在调入,这个过程对于jvm是透明的。
参考
https://www.zhihu.com/question/27654579
https://blog.csdn.net/xionghan01/article/details/52840358
https://www.uml-diagrams.org/java-thread-uml-state-machine-diagram-example.html
推荐阅读:
1、
2、
3、
4、
5、
6、
以上是关于深入玩转JAVA多线程 Thread状态与生命周期的主要内容,如果未能解决你的问题,请参考以下文章
从零开始的Java开发1-6-3 多线程:概念Thread类和Runnable接口创建线程线程的状态和生命周期sleep和join方法优先级同步线程间通信