Skip to content

The State of Java Thread

Posted on:March 20, 2023 at 10:58 PM
Share on

Java 线程状态和状态的转化

Table of contents

Open Table of contents

Thread 状态关系

Java 的线程状态描述在枚举类 java.lang.Thread.State 中,共包括如下五种状态:

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

这五种状态描述了一个线程的生命周期,线程的状态是通过下图的方式进行流转的:

Thread 方法使用

一般情况下 Thread 中最常用的方法就是 start 启动,除此之外一些其他方法可能在平常的开发中用的不多,但这些方法在一些框架中却经常出现。

yield

yield 方法让出 CPU,但不一定,一定让出!。这种可能会用在一些同时启动的线程中,按照优先级保证重要线程的执行,也可以是其他一些特殊的业务场景(例如这个线程内容很耗时,又不那么重要,可以放在后面)。

wait & notifyall

wait 和 notify/nofityall,是一对方法,有一个等待,就会有一个叫醒,否则程序就夯在那不动了。

join

join 是两个线程的合并吗?不是的! join 是让线程进入 wait ,当线程执行完毕后,会在 JVM 源码中找到,它执行完毕后,其实执行 notify,也就是 等待 和 叫醒 操作。

public class Test {

  public static void main(String[]args) throws InterruptedException{
    Thread thread = new Thread(()->{
      System.out.println("Thread before");
      try {
        Thread.sleep(3000);
      }catch(Exception e){
        e.printStackTrace();
      }
      System.out.println("Thread after");
      });
      thread.start();
      System.out.println("Main begin!");

      thread.join();
      System.out.println("Main end!");
  }

}
Main begin!
Thread before
Thread after
Main end!

首先 join() 是一个 synchronized 方法, 里面调用了 wait(),这个过程的目的是让持有这个同步锁的线程进入等待,那么谁持有了这个同步锁呢?答案是主线程,因为主线程调用了 threadA.join()方法,相当于在 threadA.join()代码这块写了一个同步代码块,谁去执行了这段代码呢,是主线程,所以主线程被 wait()了。然后在子线程 threadA 执行完毕之后,JVM 会调用 lock.notify_all(thread);唤醒持有 threadA 这个对象锁的线程,也就是主线程,会继续执行。

Share on