Java多线程基础(一):线程的六种状态

459 阅读2分钟

一、监控工具

先提一个工具,可以方便观察JVM中线程的状态,Java VisualVM 是可视化的查看JVM运行信息的工具,位于 $JAVA_HOME/bin/jvisualvm 官方文档 docs.oracle.com/javase/8/do… 在菜单工具-插件,安装 Threads Inspector 插件可以查看线程运行状态。

二、线程状态

在java.lang.Thread.State枚举中定义了JVM层面的6种线程状态。

1、NEW

Thread state for a thread which has not yet started.

未启动的线程状态。

2、RUNNABLE

Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

线程在JVM 中可运行,执行权交给 OS。

3、BLOCKED

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

线程等在获取 monitor lock,两类情况:

  • 一个线程等待 monitor lock 来进入同步代码块或同步方法;
  • 一个线程执行到同步代码块或者方法中的 Object.wait() 方法后处于 WAITING 状态,当其他线程调用 Object.notifyAll() 后再次尝试进入(reenter)同步代码块或方法时等待 monitor lock。

4、WAITING

Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:

  • Object.wait with no timeout
  • Thread.join with no timeout
  • LockSupport.park

A thread in the waiting state is waiting for another thread to perform a particular action. For example, a thread that has called Object.wait() on an object is waiting for another thread to call Object.notify() or Object.notifyAll() on that object. A thread that has called Thread.join() is waiting for a specified thread to terminate.

JVM层面的等待或者阻塞。

5、TIMED_WAITING

Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:

  • Thread.sleep
  • Object.wait with timeout
  • Thread.join with timeout
  • LockSupport.parkNanos
  • LockSupport.parkUntil

6、TERMINATED

Thread state for a terminated thread. The thread has completed execution.

线程执行结束或者异常结束。

三、Blocked 和 Waiting 状态的区别

共享资源在代码层面指的是同步代码块或者同步方法。

两种状态的出现可以简单理解成线程为了对共享资源的独占。 获取不到 monitor lock 进入 block set 处于 Blocked 状态。 进入同步代码块后发现缺少某种资源,调用 Object.wait() 先释放共享资源线程进入 wait set 处于 Waiting 状态,等待调用 Object.notifyAll() 呼唤自己出队,出队后重新尝试(reenter)获取共享资源。

简言之,Blocked 阻塞是因为锁,Waiting 阻塞是因为 Object#wait 线程间协作。

四、为什么没用 RUNNING 状态

因为JVM的RUNNABLE状态包含了线程正在执行的状态,JVM将一个可以执行的线程交给OS接管,具体的执行权在OS方。

五、线程生命周期图

网上找的一个图,感觉很清晰的描绘除了线程各个状态的流转。