Java线程都有哪些状态,他们怎么转换的,包你一次全记住

  1. Java是一种面向对象的语言
  2. Java里的一切都是对象(primitive 类型除外)
  3. 线程是Java里的
  4. 线程也是对象
  5. 线程有状态, 状态也是对象

有对象就有对应的类.想知道Java线程有哪些状态,最方便的方法, 是读代码java.lang.Thread.State.

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}

一共6个状态, 清晰明了. 注释更是十分完备.

  1. new出来没start的叫: NEW

  2. 结束了的叫: TERMINATED 这就已经记住俩了.

  3. 可以跑的叫Runnable. 应理解为, 20岁可以结婚的可以.具体结没结,不是这里考虑的问题.有可能还缺其他资源比如CPU.

  4. 在等(monitor)的叫BLOCKED. synchronized 用的锁, 就是monitor,任何对象上都有一个monitor. 这俩差不多也记住了吧.

最后这俩是一组的,等待别的线程.区别是有没有超时时间.

  1. 没超时时间的叫WAITING . 比如, 今生,你不来我不走
  2. 有超时时间的叫TIMED_WAITING. 比如, 杨过跟小龙女的十六年后再见.

应该已经记全了. 那就接着来记他们的转变关系.

线程状态转化关系图

Java线程都有哪些状态,他们怎么转换的,包你一次全记住

基础关系已经全了. 接下来逐步往里面加剩下的.

这里要把RUNNABLE当成一个复杂状态来看.分为

  1. READEY
  2. RUNNING

两个子状态, 中间通过调度器来调度. 在RUNNABLE里面

  • 只能有RUNNING来变成其他状态.
  • 其他状态只能先变为Ready
Java线程都有哪些状态,他们怎么转换的,包你一次全记住

BLOCKED

然后, 加入BLOCKED状态. 那他肯定是Running变的, 也只能变成Ready. 契机有两个

  1. I/O
  2. synchronized block

所以图是这样的.

Java线程都有哪些状态,他们怎么转换的,包你一次全记住

WAITING

加入WAITING 也很简单,记得时机就可以

由Running变成WAITING

  1. join()
  2. park()
  3. wait()

由WAITING变Ready

  1. notify()
  2. notifyAll()
Java线程都有哪些状态,他们怎么转换的,包你一次全记住

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

好了. 相信已经把各种状态的读取和转换搞得很明白了. 还是记不得的话, 就多看看图.

出自前几天推荐过的那本书. 我这里只是尝试复刻一下.Java线程都有哪些状态,他们怎么转换的,包你一次全记住


这里是K字的研究, 我是老K. 新学的标题党技巧.估计看完也记不住, 不要紧.

原文始发于微信公众号(K字的研究):Java线程都有哪些状态,他们怎么转换的,包你一次全记住

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/24863.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!