Java基础线程状态

Java基础线程状态Java 的每个线程都具有自己的状态 Thread 类中成员变量 threadStatus 存储了线程的状态 private volatile int threadStatus 0 在 Thread 类中也定义了状态的枚举 共六种 如下 public enum State NEW 新建状态 RUNNABLE 执行状态 BLOCKED 阻塞状态

大家好,我是讯享网,很高兴认识大家。



Java的每个线程都具有自己的状态,Thread类中成员变量threadStatus存储了线程的状态:

private volatile int threadStatus = 0;
讯享网

在Thread类中也定义了状态的枚举,共六种,如下:

讯享网public enum State { NEW, // 新建状态 RUNNABLE, // 执行状态 BLOCKED, // 阻塞状态 WAITING, // 无限期等待状态 TIMED_WAITING, // 有限期等待状态 TERMINATED; // 退出状态 }

threadStatus初始值为0,对应的就是NEW状态。

  • NEW:新建状态,new Thread()时处于这个状态,此时线程还未开始执行
  • RUNNABLE:执行状态,当调用了start方法后,线程处于此状态,当然此刻CPU不一定正在执行它
  • BLOCKED:阻塞状态,线程等待锁时处于此状态
  • WAITING:无限期等待状态,需要被唤醒的等待属于此状态,如Object.wait
  • TIMED_WAITING:有限期等待状态,调用一些有超时时间的等待方法会进入此状态,如Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
  • TERMINATED:退出状态,可能是正常运行完毕,也可能是抛出了异常导致线程终止

我们可以通过getState获取线程的状态:

State state = thread.getState();

接下来,我们通过示例来感受线程状态的变化。

示例一:

讯享网Thread t = new Thread(() -> { System.out.println("sleep"); // 休眠2秒 ThreadUtil.sleep(2000); System.out.println("run"); }); // 启动前先打印一下线程状态 System.out.println(t.getState()); // 启动线程 t.start(); // 启动后立即打印一次线程状态 System.out.println(t.getState()); // 每隔500毫秒打印一次线程状态 while (true) { ThreadUtil.sleep(500); System.out.println(t.getState()); }

输出:

NEW
RUNNABLE
sleep
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
run
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED

可以看出,线程创建后,初始状态为NEW;

调用start方法后状态变更为了RUNNABLE;

当线程内执行了sleep,休眠2秒钟,状态变更为了TIMED_WAITING;

当线程执行完成后,状态变更为了TERMINATED。

示例二:

本示例演示在多线程争抢锁的情况下,线程状态的变化。

private static Object lock = new Object(); public static void main(String[] args) { Runnable runnable = () -> { // 加锁 synchronized (lock) { System.out.println(Thread.currentThread().getName() + " lock"); ThreadUtil.sleep(2000); } System.out.println(Thread.currentThread().getName() + " exit"); }; Thread t1 = new Thread(runnable, "t1"); Thread t2 = new Thread(runnable, "t2"); t1.start(); t2.start(); while (true) { ThreadUtil.sleep(500); System.out.println(t1.getName() + ":" + t1.getState()); System.out.println(t2.getName() + ":" + t2.getState()); } }

输出:

t1 lock               t1获得了锁
t1:TIMED_WAITING t1 sleep,进入有限等待状态
t2:BLOCKED t2未获得锁,因此进入阻塞状态
t1:TIMED_WAITING
t2:BLOCKED
t1:TIMED_WAITING
t2:BLOCKED
t1 exit t1释放锁,执行完成,退出
t2 lock t2获得锁
t1:TERMINATED t1已经是退出状态
t2:TIMED_WAITING t2 sleep,进入有限等待状态
t1:TERMINATED   
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t2 exit t2释放锁,执行完成,退出
t1:TERMINATED t1为退出状态
t2:TERMINATED t2为退出状态

示例三:

本示例演示了线程如何进入和退出WAITING状态。Java基础线程状态

private static Object obj = new Object(); public static void main(String[] args) { Runnable runnable = () -> { synchronized (obj) { try { // 等待 obj.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("exit"); } }; Thread t1 = new Thread(runnable, "t1"); System.out.println(t1.getName() + ":" + t1.getState()); t1.start(); System.out.println(t1.getName() + ":" + t1.getState()); for (int i = 0; i < 20; i++) { ThreadUtil.sleep(500); if(i == 3) { synchronized (obj) { // 唤醒 obj.notify(); } } System.out.println(t1.getName() + ":" + t1.getState()); } }

输出:

t1:NEW
t1:RUNNABLE
t1:WAITING   调用了obj.wait()进入无限等待状态
t1:WAITING
t1:WAITING
t1:BLOCKED 主线程获得锁,进行notify,t1进入了阻塞状态
exit           t1线程退出同步块,执行完成
t1:TERMINATED t1线程退出
t1:TERMINATED

Java Thread的threadStatus字段值的更新代码位于hotspot c++源码中,JDK源码中看不到。

Java的线程状态并非是操作系统的实际线程状态,但与操作系统的线程状态是有对应关系的,后续有需要深入分析操作系统原理、hotspot源码再展开。

小讯
上一篇 2025-01-01 11:30
下一篇 2024-12-25 16:04

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/591.html