Thread.State枚举类型中定义了线程的6种状态:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING和TERMINATED。
线程在某一时刻只能拥有一种状态,但是在线程的整个生命周期,线程的状态会发生变化。
各状态的说明NEW:线程已经被创建,但还没调用start()。此时的线程是不可运行的,CPU将不会为其分配时间;
RUNNABLE:当新创建的线程调用了start(),线程便进入了RUNNABLE状态。RUNNABLE状态是指可以获得CPU运行时间的状态,如果线程在此状态下,线程有两种子状态,一种是等待CPU时间,另一种是获得了CPU时间在执行代码。
BLOCKED:线程无法获取对象锁时的状态。当线程试图获取某个锁,而锁被其他线程持有,则该线程进入BLOCKED状态。此状态下线程会阻塞,当线程成功获取到锁,线程将切换为RUNNABLE状态。BLOCKED状态无法获得CPU运行时间。
WAITING(无限等待):线程在执行过程中,主动出让自己CPU运行时间,让其他线程先执行,自己等待其它线程的特定操作后再恢复执行。WAITING状态的线程不能自动唤醒的,必须等待另外的线程调用notify()或notifyAll()方法才能够唤醒。
TIMED_WAITING(计时等待):与WAITING状态相似,TIMED_WAITING增加了时间限制,其实没有外部信号,在等待时间超时后,线程自动恢复。
TERMINATED:线程的终止态,当线程执行完自己的任务,或在执行任务中发生了异常,线程都会进入TERMINATED,表示线程已经到了生命周期的末尾。
下图是关于线程间各状态切换的过程及发生状态切换的一些条件。
【java面试】探究Java线程状态及转换
以下是一些测试代码,可以运行下清晰的了解到状态。
各状态切换测试:
public class ThreadStateTest {
public static void main(String[] args){
// 没调用start方法查看下thread状态 NEW
threadStateNew();
// 调用start方法查看thread状态 RUNNABLE
workingThread();
// thread调用join方法查看状态 TERMINATED
threadStateTerminate();
// main线程持有锁(可重入锁)的同时查看thread状态 WAITING
threadBlockedByLock();
// 多个线程同时竞争同一把锁时,未获得锁的线程处于 BLOCKED
threadBlockedBySynchronized();
threadSleep();
threadWait();
threadTimeWait();
}
private static void threadStateNew(){
System.out.println("--------------------------");
System.out.print("Never Start Thread State:");
Thread thread = new Thread(()->{
}, "Thread Never Start");
//print NEW
System.out.println(thread.getState());
System.out.println("--------------------------");
}
private static void workingThread(){
System.out.println("--------------------------");
Thread thread = new Thread(()->{
for(int i=0; i<100; i++){
doSomeElse();
}
});
thread.start();
doSomeElse();
//print RUNNABLE
System.out.println("Working Thread State:" + thread.getState());
System.out.println("--------------------------");
}
private static void threadStateTerminate(){
System.out.println("--------------------------");
System.out.print("Finish Job Thread State:");
Thread thread = new Thread(()->{
}, "Thread Finish Job");
thread.start();
try {
//Main Thread Will Wait util this thread finished job
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print TERMINATED
System.out.println(thread.getState());
System.out.println("--------------------------");
}
private static void threadBlockedByLock(){
System.out.println("--------------------------------------");
System.out.println("Thread State Blocked By Lock:");
ReentrantLock lock = new ReentrantLock();
Thread thread = new Thread(lock::lock, "Blocked Thread");
lock.lock();
try {
thread.start();
doSomeElse();
//print WAITING
System.out.println(thread.getState());
} catch (Exception e){
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("--------------------------------------");
}
private static void threadBlockedBySynchronized(){
System.out.println("--------------------------------------");
System.out.println("Thread Blocked By Synchronized:");
Thread thread = new Thread(() -> {
synchronized (ThreadStateTest.class){
System.out.println("thread成功获取synchronized锁");
}
}, "Blocked by Synchronized Thread");
thread.start();
synchronized (ThreadStateTest.class){
System.out.println("main成功获取synchronized锁");
doSomeElse();
// print BLOCKED 怎么还能打印RUNNABLE???
// 阻塞main线程3s,等待thread去获取锁
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread State is:" + thread.getState());
System.out.println("锁释放...");
}
System.out.println("--------------------------------------");
}
private static void threadSleep(){
System.out.println("--------------------------");
System.out.print("Sleeping Thread:");
Thread thread = new Thread(()->{
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Thread sleep");
thread.start();
doSomeElse();
//print TIMED_WAITING
System.out.println(thread.getState());
System.out.println("--------------------------");
}
private static void threadWait(){
System.out.println("--------------------------");
System.out.print("Thread Waiting:");
Object lock = new Object();
Thread threadA = new Thread(()->{
synchronized (lock){
try {
lock.wait();
for(int i=0; i<100; i++){
doSomeElse();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Thread Waiting");
Thread threadB = new Thread(()->{
synchronized (lock){
//print WAITING
System.out.println("Before Notify, Thread A State:" + threadA.getState());
lock.notify();
//print BLOCKED
System.out.println("After Notify, Thread A State:" + threadA.getState());
}
});
threadA.start();
doSomeElse();
threadB.start();
try {
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print RUNNABLE
System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
System.out.println("--------------------------");
}
private static void threadTimedWait(){
System.out.println("--------------------------");
System.out.print("Thread Waiting:");
Object lock = new Object();
Thread threadA = new Thread(()->{
synchronized (lock){
try {
lock.wait(1000);
for(int i=0; i<100; i++){
doSomeElse();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Thread Waiting");
Thread threadB = new Thread(()->{
synchronized (lock){
//print TIMED_WAITING
System.out.println("Before Notify, Thread A State:" + threadA.getState());
lock.notify();
//print BLOCKED
System.out.println("After Notify, Thread A State:" + threadA.getState());
}
});
threadA.start();
doSomeElse();
threadB.start();
try {
threadB.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
//print RUNNABLE
System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
System.out.println("--------------------------");
}
private static void doSomeElse(){
double meanless = 0d;
for(int i=0; i<10000; i++){
meanless += Math.random();
}
}
}
CPU时间运行测试:
public class ThreadCPUTimeTest {
public static void main(String[] args) {
testBlockedThreadCPUTime();
}
protected static void testBlockedThreadCPUTime() {
Object lock = new Object();
Thread threadA = new Thread(() -> {
synchronized (lock) {
doSomethingElse();
}
}, "ThreadA: Blocked because of synchronized");
Thread threadB = new Thread(() -> {
synchronized (lock) {
try {
threadA.start();
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "ThreadB: With Monitor But Sleep");
threadB.start();
//Main Thread Executing Job
for (int i = 0; i < 100000; i++) {
doSomethingElse();
}
}
private static void doSomethingElse() {
double meanless = 0d;
for (int i = 0; i < 10000; i++) {
meanless += Math.random();
}
}
}



