目录
一 线程的六种状态
1.1 NEW状态
1.2 RUNNABLE状态
1.3 TERMINATE状态
1.4 WAITING状态
1.5 TIMED_WAITING状态
1.6 BLOCKED状态
二 六种状态间的状态转换
在 Java 中,线程是操作系统调度的基本单位。为了更好地理解线程的行为和生命周期,Java 定义了 6 种线程状态,这些状态由 Thread.State 枚举类表示。本文将详细介绍每种状态的含义以及状态之间的切换条件。
一 线程的六种状态
线程的状态是一个枚举类型 Thread.State,因此可以通过以下代码可以观察到线程的所有状态:
public class Test1 {
public static void main(String[] args) throws InterruptedException {
for (Thread.State state : Thread.State.values()) {
System.out.println(state);
}
}
}
运行结果:
解释线程的六个状态:
NEW:线程处于已创建状态,还未启动。 RUNNABLE:线程已启动,处于工作状态或即将工作状态。 BLOCKED:线程处于阻塞状态,等待其他线程执行完毕。 WAITING:线程处于等待状态,无限制等待状态。 TIMED_WAITING:线程处于定时的等待状态。 TERMINATE:线程已执行完毕。
下面来一一介绍。
1.1 NEW状态
含义:当前已经有了Thread对象,但还没在CPU的内核上创建线程,就是还没有使用start方法来创建线程。
Thread t = new Thread();
System.out.println("t.getState() = " + t.getState());
运行结果:
1.2 RUNNABLE状态
含义:RUNNABLE状态表示就绪状态,意思是该状态的线程随时都可以被调度到CPU上运行或者已经在CPU上运行。
public class Test1 {
public static void main(String[] args) {
Thread t = new Thread(() ->{
System.out.println("线程运行中");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t.start();
System.out.println("t.getState() = " + t.getState());
}
}
运行结果:
1.3 TERMINATE状态
含义:线程已经完成执行。
public class Test1 {
public static void main(String[] args) {
Thread t = new Thread(() ->{
System.out.println("线程运行中");
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("t.getState() = " + t.getState());
}
}
运行结果:
1.4 WAITING状态
含义:线程无限期等待另一个线程执行特定操作。
public class Test1 {
public static void main(String[] args) {
Thread t1 = new Thread(() ->{
while (true) {
}
});
Thread t2 = new Thread(() ->{
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("t2.getState() = " + t2.getState());
}
}
运行结果:
1.5 TIMED_WAITING状态
含义:线程在指定时间内等待另一个线程执行特定操作。
public class Test1 {
public static void main(String[] args) {
Thread t1 = new Thread(() ->{
while (true) {
}
});
Thread t2 = new Thread(() ->{
try {
t1.join(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("t2.getState() = " + t2.getState());
}
}
运行结果:
1.6 BLOCKED状态
含义:当一个线程试图进入一个同步块或方法(通过 synchronized 关键字),但该同步块或方法已经被其他线程持有的锁锁定时,这个线程将进入 BLOCKED 状态。
public class Test2 {
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(() ->{
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
Thread t2 = new Thread(() ->{
synchronized (lock) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t1.start();
t2.start();
System.out.println("t1.getState() = " + t1.getState());
System.out.println("t2.getState() = " + t2.getState());
}
}
运行结果:
在 Java 多线程中,synchronized 关键字用于确保同一时刻只有一个线程可以执行同步块或方法。当多个线程竞争同一个锁时,未获取到锁的线程会进入 BLOCKED 状态,直到锁被释放;而持有锁的线程即使调用 Thread.sleep() 也不会释放锁,其状态仍为 RUNNABLE。线程状态的变化由锁的竞争和调度决定,实际结果可能因线程调度的不确定性而有所不同。上述代码中是t1得到了锁,所以t2就由锁竞争引起的阻塞等待,所以t2的状态就是BLOCKED。
二 六种状态间的状态转换