线程状态

该图片由Peggy Choucair在Pixabay上发布

1. 线程状态

// Thread.State 源码

1
2
3
4
5
6
7
8
9
10

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

1.1 new

一个已经创建而未启动的线程处于改状态,此时还未调用start()方法;

1
2
3
4

 Thread thread = new Thread(() -> {});
    System.out.println(thread.getState()); // 输出 NEW 
    

注意:一个线程实例只能被启动一次

1.2 RUNNABLE

该状态可以被看成一个复合状态。它包含两个子状态READY和RUNNING。前者表示处于该状态的线程可以被线程调度器调度而使之处于RUNNING状态。后者表示处于该状态的的线程正在运行,即相应线程对象的run方法所对应的指令正在由处理器执行;执行Thread.yield()的线程,其状态可能会由RUNNING转换为READY。处于READY子状态的线程也被成为活跃线程

1.3 BLOCKED

一个线程发起一个阻塞式I/O(Blocking I/O)操作后,或者申请一个由其它线程持有的独占资源(比如锁)时,相应的线程会处于该状态;处于BLOCKED状态的线程并不会占用处理器资源;当阻塞式I/O操作完成后,或者线程获得了其申请的资源,该线程的状态可以转换为RUNNABLE;

1.4 WAITING

等待状态;一个线程执行了某些特定方法之后会处于这种等待其他线程执行另外一些特定操作的状态;

调用如下3个方法会使线程进入等待状态:

  • Object.wait():使当前线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒。该方法只能在同步方法中调用。如果当前线程不是锁的持有者,该方法抛出一个IllegalMonitorStateException异常。
  • Thread.join():等待线程执行完毕,底层调用的是Object实例的wait方法;
  • LockSupport.park():除非获得调用许可,否则禁用当前线程进行线程调度。

1.5 TIME_WAITING

超时等待状态。该状态和WAITING类似,差别在于处于该状态的线程并非无限制的等待其他线程执行特定操作,而是处于有时间限制的等待状态,当其他线程没有在指定时间内执行该线程所期望的特定操作时,该线程状态会自动转换为RUNNABLE;

调用如下方法会使线程进入超时等待状态:

  • Thread.sleep(long millis):使当前线程睡眠指定时间;
  • Object.wait(long timeout):线程休眠指定时间,等待期间可以通过notify()/notifyAll()唤醒;
  • Thread.join(long millis):等待当前线程最多执行millis毫秒,如果millis为0,则会一直执行;
  • LockSupport.parkNanos(long nanos):除非获得调用许可,否则禁用当前线程进行线程调度指定时间;
  • LockSupport.parkUntil(long deadline):同上,也是禁止线程进行调度指定时间;

1.6 TERMINATED

终止状态。此时线程已执行完毕。

1.7 线程状态转换图:

参考资料1-java线程的状态及主要转化方法

参考资料2- 《Java多线程编程实战指南-核心篇》 《Java多线程编程核心技术》

坚持原创技术分享,您的支持将鼓励我继续创作!