1.线程状态

public class Thread implements Runnable {
public enum State {
NEW,

RUNNABLE,

BLOCKED,

WAITING,

TIMED_WAITING,

TERMINATED;
}

public State getState() {
//获取当前线程状态
return sun.misc.VM.toThreadState(threadStatus);
}
}

如线程源码所示,共定义了6种线程状态,NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING以及TERMINATED。

2.线程状态转换

线程6个状态之间的转换如下图所示。

6.线程状态_开发语言

  • NEW(初始):实现Runnable接口或继承Thread类创建一个线程,但还未调用start()方法,此时线程就进入初始状态。
  • RUNNABLE(运行):Java将READY(就绪)和RUNNING(运行中)两种状态合称为运行状态。线程创建后,其他线程(如main线程)调用了该线程的start()方法,那么该线程就会被放置到可运行的线程池中,等待JVM调度,此时处于就绪状态。就绪状态的线程获得CPU的执行权后变为运行中状态。
  • BLOCKED(同步阻塞):运行的线程申请获取对象的同步锁时,若该同步锁被别的线程,JVM就会将该线程置为同步阻塞状态。
  • WAITING(等待阻塞):运行的线程执行wait()方法时,JVM就会将该线程置为等待阻塞状态,进入这个状态的线程,必需依靠其它线程调用notify()或notifyAll()方法唤醒。
  • TIMED_WAITING(超时等待阻塞):运行的线程执行sleep()或join()方法、或者发出了IO请求时,JVM就会将该线程置为阻塞状态。无需唤醒,当sleep()超时、join()方法加入线程执行完毕、IO处理完毕时,线程重新进入READY(就绪)状态。
  • TERMINATED(消亡):线程已经执行完毕或遇到异常退出时便会消亡。

3.NEW、RUNNABLE以及TERMINATED状态的代码演示

/**
* 描述:展示线程的NEW、RUNNABLE、TERMINATED状态。
* 即使是正在运行的线程,也是RUNNABLE状态,而不是RUNNING。
*/
public class NewRunnableTerminated implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 1000; i++) {
System.out.println("正在输出" + i);
}
}

public static void main(String[] args) {
Thread thread = new Thread(new NewRunnableTerminated());
System.out.println("当前线程状态:" + thread.getState());
thread.start();
System.out.println("当前线程状态:" + thread.getState());
try {
//休眠10ms的作用是使得主线程不要执行太快,在子线程还未启动前就运行结束了,这样便可以在子线程执行过程中打印线程状态
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程状态:" + thread.getState());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程状态:" + thread.getState());
}
}

执行结果如下所示,在线程创建后未调用start()方法前,线程状态为NEW,调用start()方法后,线程状态为RUNNABLE。然后执行子线程任务,在执行过程中打印线程状态依然为RUNNABLE,最后线程执行完毕后,线程状态为TERMINATED。如果子线程打印的数值比较少,比如10,那么倒数第二个的线程状态可能为TERMINATED。值得注意的是,如果在线程执行完毕后,再次调用start()方法时,会抛java.lang.IllegalThreadStateException异常。

当前线程状态:NEW
当前线程状态:RUNNABLE
正在输出1
正在输出2
正在输出3
......
当前线程状态:RUNNABLE
......
正在输出998
正在输出999
正在输出1000
当前线程状态:TERMINATED
当前线程状态:NEW
当前线程状态:RUNNABLE
正在输出1
正在输出2
正在输出3
正在输出4
正在输出5
正在输出6
正在输出7
正在输出8
正在输出9
正在输出10
当前线程状态:TERMINATED
当前线程状态:TERMINATED

4.BLOCKED、WAITING以及TIMED_WAITING状态的代码演示

/**
* 描述:展示BLOCKED, WAITING, TIMED_WAITING的状态。
*/
public class BlockedWaitingTimedWaiting implements Runnable {
@Override
public void run() {
syn();
}

private synchronized void syn() {
try {
Thread.sleep(1000);
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public static void main(String[] args) {
BlockedWaitingTimedWaiting blockedWaitingTimedWaiting = new BlockedWaitingTimedWaiting();

Thread thread1 = new Thread(blockedWaitingTimedWaiting);
thread1.start();

Thread thread2 = new Thread(blockedWaitingTimedWaiting);
thread2.start();

try {
//休眠10ms的作用是使得主线程不要执行太快,在子线程还未启动前就运行结束了,这样便可以在子线程执行过程中打印线程状态
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("线程1当前状态:" + thread1.getState());
System.out.println("线程2当前状态:" + thread2.getState());
try {
//这里大于1000ms的作用是让线程1或线程2执行完sleep方法后执行wait方法
Thread.sleep(1300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程1当前状态:" + thread1.getState());
}
}

程序执行结果如下所示。

线程1当前状态:TIMED_WAITING
线程2当前状态:BLOCKED
线程1当前状态:WAITING