-
Java是一种面向对象的语言 -
Java里的一切都是对象(primitive 类型除外) -
线程是Java里的 -
线程也是对象 -
线程有状态, 状态也是对象
有对象就有对应的类.想知道Java线程有哪些状态,最方便的方法, 是读代码java.lang.Thread.State
.
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
一共6个状态, 清晰明了. 注释更是十分完备.
-
new出来没
start
的叫: NEW -
结束了的叫: TERMINATED 这就已经记住俩了.
-
可以跑的叫
Runnable
. 应理解为, 20岁可以结婚的可以
.具体结没结,不是这里考虑的问题.有可能还缺其他资源比如CPU. -
在等(
monitor
)的叫BLOCKED. synchronized 用的锁, 就是monitor
,任何对象上都有一个monitor
. 这俩差不多也记住了吧.
最后这俩是一组的,等待别的线程
.区别是有没有超时时间.
-
没超时时间的叫 WAITING
. 比如,今生,你不来我不走
-
有超时时间的叫 TIMED_WAITING
. 比如,杨过跟小龙女的十六年后再见
.
应该已经记全了. 那就接着来记他们的转变关系.
线程状态转化关系图

基础关系已经全了. 接下来逐步往里面加剩下的.
这里要把RUNNABLE
当成一个复杂状态来看.分为
-
READEY -
RUNNING
两个子状态, 中间通过调度器来调度. 在RUNNABLE里面
-
只能有RUNNING来变成其他状态. -
其他状态只能先变为Ready

BLOCKED
然后, 加入BLOCKED
状态. 那他肯定是Running变的, 也只能变成Ready
. 契机有两个
-
I/O -
synchronized block
所以图是这样的.

WAITING
加入WAITING 也很简单,记得时机就可以
由Running变成WAITING
-
join() -
park() -
wait()
由WAITING变Ready
-
notify() -
notifyAll()

TIMED_WAITING
这个,我就不画了.😄 因为他就是WAITING的加时间版本. 外加一个 Sleep. 主要原因是, 我画太烂了. 完整图可以文末.
代码时间
接下来,分享几段代码. 如何从线程上读取出这6种状态.
如何读取到NEW状态
Thread thread = new Thread();
System.out.println("state:" + thread.getState());
// state: NEW
如何读取到RUNNABLE
Thread thread = new Thread();
thread.start()
System.out.println("state:" + thread.getState());
// state: RUNNABLE
如何读取到TERMINATED
Thread thread = new Thread();
thread.start()
Thread.sleep(10000);
//等一下,等线程跑完就是这个状态了
System.out.println("state:" + thread.getState());
// state: TERMINATED
如何读取到BLOCKED
这个其实分两类, IO 阻塞. synchronized阻塞. 不太关心IO, 就看同步块吧.
Thread[] t = new Thread[2];
t[0] = new Thread(() -> {
synchronized (t) {
while (true) {
}
}
});
t[1] = new Thread(() -> {
synchronized (t) {
}
});
t[0].start(); t[1].start();
Thread.sleep(3000);
System.out.println("state:" + t[1].getState());
//state: BLOCKED
t[0]和t[1]竞争对象t上的同一个monitor,同一把锁. t[0]不退出,t[1]就进入了block状态.
如何读取到WAITING, TIMED_WAITING
这俩都是类似的,最简单的用join就可以.
Thread[] tout = new Thread[1];
tout[0] = new Thread(() -> {
Thread inner = new Thread(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
});
try {
inner.start();
inner.join();
} catch (InterruptedException e) {
}
});
tout[0].start();
Thread.sleep(1000);
System.out.println("state:" + tout[0].getState());
//WAITING
//把上面的join加上时间参数, 就可以得到
//TIMED_WAITING
好了. 相信已经把各种状态的读取和转换搞得很明白了. 还是记不得的话, 就多看看图.
这里是K字的研究, 我是老K. 新学的标题党技巧.估计看完也记不住, 不要紧.
原文始发于微信公众号(K字的研究):Java线程都有哪些状态,他们怎么转换的,包你一次全记住
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/24863.html