一、状态列举
Java线程到底有几种状态,其实只要打开一下JDK源码,看一下java.lang.Thread
类就知道了,java.lang.Thread
定义了一个内部枚举java.lang.Thread.State
,部分源码如下:
/** * A thread can be in only one state at a given point in time. * These states are virtual machine states which do not reflect * any operating system thread states. * 一个线程在特定的时刻,只能有一个状态。 * 这些状态是虚拟机的状态,不能反映任何操作系统的线程状态 * @since 1.5 */ public enum State { /** * Thread state for a thread which has not yet started. * 线程未开始的状态 */ NEW, /** * 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中运行, * 但也有可能在等待操作系统的其他资源,例如处理器 */ RUNNABLE, /** * 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 * 阻塞状态的线程在等待一个监视器锁去进入同步代码块/方法, * 或者调用后重新进入同步代码块/方法 */ BLOCKED, /** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the following methods: * Object.wait() * Thread.join() * LockSupport.park() * A thread in the waiting state is waiting for another thread to * perform a particular action. * 由于调用了Object.wait()、Thread.join()、LockSupport.park()其中一个方法,线程进入等待状态 * 处于等待状态的线程,正在在等待另一个线程执行特定的操作 */ 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() * LockSupport.parkNanos() * LockSupport.parkUntil() * 有指定等待时间的线程等待状态 * 由于调用了Thread.sleep(long)、Object.wait(long)、Thread.join(long)、 * LockSupport.parkNanos(long)、LockSupport.parkUntil(long)其中一个方法并传入了正(数)时间参数, * 线程处于有时间限制的等待状态 */ TIMED_WAITING, /** * Thread state for a terminated thread. * The thread has completed execution. * 线程已经执行完成,处于终止状态 */ TERMINATED; }
根据上述代码,可以知道Java线程有六个状态:
- NEW(新建)
创建了Thread对象,但是还没调用start方法——系统内核中还该线程还没有创建出来(安排了工作,还未开始行动)
- RUNNABLE(可运行)
就绪状态:1、程序正在CPU上运行 2、还没在CPU上运行,但是已经准备好了(调用了start方法后——可工作的,又可以分为正在工作和即将开始工作)
BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(指定时间的等待)
阻塞状态,Java中把阻塞状态按照不同的原因又细分为三种不同状态。BLOCKED等待锁、WAITING线程中调用了wait、TIMED_WAITING线程中调用了sleep(这几个都表示排队等着其他事情)
- TERMINATED(终止)
系统里面的线程已经执行完毕了,销毁了(相当于线程的run执行完了,工作完成了)但是Thread对象还在
线程之间的转换关系如下:
值得注意的是,Java线程是不区分Ready(就绪)和Running(运行)的,它们都是Runnable状态,我把他们画出来,是为了强调,也便于理解。
二、 实例分析
🌰实例一
线程状态:NEW -> RUNNABLE -> TERMINATED
package Thread; public class demo7 { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("该线程正在运行,thread线程状态:" + Thread.currentThread().getState().toString()); // 返回当中执行的线程对象的引用 } }); System.out.println("Thread被实例化,start()还未调用,thread线程状态:" + thread.getState().toString()); // 程序走到这里,thread线程还未被在操作系统内核中创建,thread当前线程还是NEW thread.start(); // 程序走到这里,当调用start后,thread线程开始在操作系统内核中创建,该线程所对应的PCB加入到系统链表,参与系统调度,只是参与系统调度不一定马上执行,也可能只是即将开始执行 System.out.println("start()方法被调用,thread线程状态:" + thread.getState().toString()); thread.join(); // main线程等thread线程执行完了后在执行 System.out.println("thread线程执行完了后,thread线程状态:" + thread.getState().toString()); } }
🔔提醒
我们上述代码展示了主线程(main) 展示了thread线程的状态,注意当我们已进入主线程的入口main方法,主线程就已经被创建好了,进入了RUNNABLE状态,所有你在main打印的主线程的状态都是RUNNSABLE,不会出现NEW状态
🌰实例二
线程状态:NEW -> RUNNABLE -> TIMED_WAITING -> RUNNABLE -> TERMINATED
public static void main(String[] args) throws Exception { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sleep结束,thread线程状态:" + Thread.currentThread().getState().toString()); } }); System.out.println("未调用start(),thread线程状态:" + thread.getState().toString()); thread.start(); // 睡眠200毫秒,让thread被调度起来,进入sleep Thread.sleep(200); System.out.println("线程sleep,thread线程状态:" + thread.getState().toString()); // 睡眠2秒,让thread执行完成 Thread.sleep(2000); System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString()); }
执行结果
未调用start(),thread线程状态:NEW 执行run(),thread线程状态:RUNNABLE 线程sleep,thread线程状态:TIMED_WAITING sleep结束,thread线程状态:RUNNABLE 线程执行完成,thread线程状态:TERMINATED
🌰实例三
线程状态:NEW -> RUNNABLE -> BLOCKED -> RUNNABLE -> TERMINATED
private static Object lock = new Object(); public static void main(String[] args) throws Exception { Thread thread = new Thread(new Runnable() { @Override public void run() { System.out.println("执行run(),thread线程状态:" + Thread.currentThread().getState().toString()); synchronized(lock) { } System.out.println("synchronized结束,thread线程状态:" + Thread.currentThread().getState().toString()); } }); System.out.println("未调用start(),thread线程状态:" + thread.getState().toString()); synchronized(lock) { thread.start(); Thread.sleep(200); System.out.println("线程synchronized,thread线程状态:" + thread.getState().toString()); } // 睡眠2秒,让thread执行完成 Thread.sleep(2000); System.out.println("线程执行完成,thread线程状态:" + thread.getState().toString()); }
执行结果
未调用start(),thread线程状态:NEW 执行run(),thread线程状态:RUNNABLE 线程synchronized,thread线程状态:BLOCKED synchronized结束,thread线程状态:RUNNABLE 线程执行完成,thread线程状态:TERMINATED