Java的生命周期和线程状态详细指南

2021年4月11日15:44:17 发表评论 630 次浏览

一种线Java中的任何时间点都处于以下任一状态。线程在任何时刻都仅处于所示状态之一:

  1. New新的
  2. 可运行
  3. 受阻
  4. 等候
  5. 定时等待
  6. 已终止

下图显示了线程在任何时刻的各种状态。

Java的生命周期和线程状态1

图片来源:

Core Java Vol 1, 9th Edition, Horstmann, Cay S.&Cornell, Gary_2013

线程的生命周期

新线程:

创建新线程时, 它处于新状态。当线程处于此状态时, 该线程尚未开始运行。当线程处于新状态时, 它的代码尚未运行且尚未开始执行。

可运行状态:

准备运行的线程将移至可运行状态。在这种状态下, 线程可能实际上正在运行, 或者在任何时候都可以运行。线程调度程序负责给线程运行时间。

多线程程序为每个单独的线程分配固定的时间量。每个线程都会运行一会儿, 然后暂停并将CPU移交给另一个线程, 以便其他线程可以运行。发生这种情况时, 所有准备运行, 等待CPU和当前运行的线程的线程都处于可运行状态。

阻止/等待状态:

线程暂时处于非活动状态时, 处于以下状态之一:

  • 受阻
  • 等候

例如, 当线程在等待I/O完成时, 它处于阻塞状态。线程调度程序负责重新激活并调度被阻止/等待的线程。处于这种状态的线程无法继续执行, 直到将其移到可运行状态为止。这些状态下的任何线程都不会消耗任何CPU周期。

当线程尝试访问当前由其他线程锁定的受保护代码段时, 该线程处于阻塞状态。当受保护的部分被解锁时, 调度将选择对该部分阻塞的线程之一并将其移至可运行状态。而一个线程在某种条件下等待另一个线程时处于等待状态。当满足此条件时, 将通知调度程序, 并将等待线程移至可运行状态。

如果当前正在运行的线程移至阻塞/等待状态, 则线程调度程序将另一个处于可运行状态的线程调度为运行。线程调度程序负责确定要运行哪个线程。

定时等待:

当线程调用带有超时参数的方法时, 线程处于定时等待状态。线程处于此状态, 直到超时完成或收到通知为止。例如, 当线程调用睡眠或条件等待时, 它将移至定时等待状态。

终止国:

线程由于以下原因之一而终止:

  • 因为它正常存在。当线程代码完全由程序执行时, 会发生这种情况。
  • 因为发生了一些异常错误事件, 例如分段错误或未处理的异常。

处于终止状态的线程不再消耗任何CPU周期。

用Java实现线程状态

在Java中, 要获取线程的当前状态, 请使用Thread.getState()获取线程当前状态的方法。 Java提供java.lang.Thread.State定义线程状态的ENUM常量的类, 其摘要如下:

常量类型:

Declaration: public static final Thread.State NEW

描述:尚未启动的线程的线程状态。

常量类型:

可运行

Declaration: public static final Thread.State RUNNABLE

描述:可运行线程的线程状态。处于可运行状态的线程正在Java虚拟机中执行, 但是它可能正在等待来自操作系统(例如处理器)的其他资源。

常量类型:

受阻

Declaration: public static final Thread.State BLOCKED

描述:线程的线程状态被阻塞, 等待监视器锁定。处于阻塞状态的线程在调用Object.wait()之后正在等待监视器锁定输入同步的块/方法或重新输入同步的块/方法。

常量类型:

等候

Declaration: public static final Thread.State WAITING

描述:等待线程的线程状态。等待线程的线程状态。由于调用以下方法之一, 线程处于等待状态:

  • Object.wait没有超时
  • 线程连接没有超时
  • LockSupport.park

处于等待状态的线程正在等待另一个线程执行特定操作。

常量类型:

定时等待

Declaration: public static final Thread.State TIMED_WAITING

描述:具有指定等待时间的等待线程的线程状态。由于以指定的正等待时间调用以下方法之一, 因此线程处于定时等待状态:

  • 线程睡眠
  • Object.wait超时
  • Thread.join与超时
  • LockSupport.parkNanos
  • LockSupport.parkUntil

常量类型:

已终止

Declaration: public static final Thread.State TERMINATED

描述:终止线程的线程状态。线程已完成执行。

//Java program to demonstrate thread states
class thread implements Runnable
{
     public void run()
     {
         //moving thread2 to timed waiting state
         try
         {
             Thread.sleep( 1500 );
         } 
         catch (InterruptedException e) 
         {
             e.printStackTrace();
         }
          
         System.out.println( "State of thread1 while it called join() method on thread2 -" +
             Test.thread1.getState());
         try
         {
             Thread.sleep( 200 );
         } 
         catch (InterruptedException e) 
         {
             e.printStackTrace();
         }     
     }
}
  
public class Test implements Runnable
{
     public static Thread thread1;
     public static Test obj;
      
     public static void main(String[] args)
     {
         obj = new Test();
         thread1 = new Thread(obj);
          
         //thread1 created and is currently in the NEW state.
         System.out.println( "State of thread1 after creating it - " + thread1.getState());
         thread1.start();
          
         //thread1 moved to Runnable state
         System.out.println( "State of thread1 after calling .start() method on it - " + 
             thread1.getState());
     }
      
     public void run()
     {
         thread myThread = new thread();
         Thread thread2 = new Thread(myThread);
          
         //thread1 created and is currently in the NEW state.
         System.out.println( "State of thread2 after creating it - " + thread2.getState());
         thread2.start();
          
         //thread2 moved to Runnable state
         System.out.println( "State of thread2 after calling .start() method on it - " + 
             thread2.getState());
          
         //moving thread1 to timed waiting state
         try
         {
             //moving thread1 to timed waiting state
             Thread.sleep( 200 );
         } 
         catch (InterruptedException e) 
         {
             e.printStackTrace();
         }
         System.out.println( "State of thread2 after calling .sleep() method on it - " + 
             thread2.getState() );
          
          
         try 
         {
             //waiting for thread2 to die
             thread2.join();
         } 
         catch (InterruptedException e) 
         {
             e.printStackTrace();
         }
         System.out.println( "State of thread2 when it has finished it's execution - " + 
             thread2.getState());
     }
      
}

输出如下:

State of thread1 after creating it - NEW
State of thread1 after calling .start() method on it - RUNNABLE
State of thread2 after creating it - NEW
State of thread2 after calling .start() method on it - RUNNABLE
State of thread2 after calling .sleep() method on it - TIMED_WAITING
State of thread1 while it called join() method on thread2 -WAITING
State of thread2 when it has finished it's execution - TERMINATED

说明:创建新线程时, 该线程处于NEW状态。在线程上调用.start()方法时, 线程调度程序将其移至Runnable状态。每当在线程实例上调用join()方法时, 执行该语句的当前线程将等待该线程移至Terminated状态。因此, 在将最终语句打印在控制台上之前, 程序将在线程2上调用join(), 使线程1等待线程2完成其执行并移至"已终止"状态。线程1之所以进入等待状态, 是因为它在线程2上调用了join, 因此正在等待线程2完成执行。

使用的参考:甲骨文, Core Java Vol 1, 9th Edition, Horstmann, Cay S.&Cornell, Gary_2013

如果发现任何不正确的地方, 或者想分享有关上述主题的更多信息, 请写评论。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: