【JAVA并发】Thread线程状态和状态切换实战
本文通过两个示例演示了Java线程的BLOCKED状态。第一个示例使用synchronized关键字展示两个线程竞争锁资源时,未获得锁的线程会处于BLOCKED状态。第二个示例模拟生产者-消费者模式,展示了调用wait()方法后线程从RUNNABLE转为WAITING,被notifyAll()唤醒后转为BLOCKED状态重新竞争锁。文中还强调了volatile关键字保证可见性但不保证原子性,以及w
序言
闲来无事,记录学习历程,交个朋友。欢迎讨论碰撞,产生好的解决方案!!!👏👏👏
背景
学习一下Java的线程,巩固基础
Thread 线程状态

状态分析
BLOCKED
线程处于阻塞状态
1、等待进去同步块或者代码(synchronized)
2、调用Object.wait之后被唤醒
- 是Object类的方法,用于线程间通信。
- 必须在同步块(synchronized)中调用,否则会抛出IllegalMonitorStateException。
- 调用wait()的线程会释放持有的锁,并进入等待状态,直到其他线程调用同一个对象的notify()或notifyAll()方法,或者被中断。
- 通常用于条件等待,即线程等待某个条件成立。
synchronized 演示
定义两个线程Worker-1、Worker-2来抢临界资源,Monitor来监控线程的状态。从结果可以看出没有抢到锁的线程的状态就是BLOCKED
volatile:可以保证临界资源的可见性!!!无法保证原子性!!!
package com.gyg.thread.demo1;
public class TestBLOCKED {
private static volatile boolean running = true;
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (running) {
synchronized (lock) {
for (int i = 0; i < 1000; i++) Math.sin(i);
}
}
}, "Worker-1");
Thread thread2 = new Thread(() -> {
while (running) {
synchronized (lock) {
for (int i = 0; i < 1000; i++) Math.cos(i);
}
}
}, "Worker-2");
// 监控线程
Thread monitor = new Thread(() -> {
while (running) {
try {
Thread.sleep(1000);
System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
} catch (Exception e) {
break;
}
}
}, "Monitor");
monitor.start();
thread1.start();
thread2.start();
Thread.sleep(10000);
running = false;
}
}
E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=57889” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestBLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: RUNNABLE, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: RUNNABLE
Worker1 status: TERMINATED, Worker2 status: TERMINATEDProcess finished with exit code 0
Object.wait演示
模拟队列的工作模式,调用wait方法后,线程有RUNNABLE转到WAITING,当调用notifyAll之后,状态由WAITING变为BLOCKED,继续抢临界资源。
package com.gyg.thread.demo1;
import java.util.LinkedList;
import java.util.Queue;
public class TestBLOCKED2 {
private static volatile boolean running = true;
private static final Object lock = new Object();
private static Queue<Integer> queue = new LinkedList<>();
private static int capacity = 10; // Set a default capacity
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (running) {
synchronized (lock) {
while (queue.size() >= capacity) {
try {
lock.wait(); // 队列已满,等待
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
queue.add(1);
lock.notifyAll(); // 唤醒等待的消费者线程
}
}
}, "Worker-1");
Thread thread2 = new Thread(() -> {
while (running) {
synchronized (lock) {
while (queue.isEmpty()) {
try {
lock.wait(); // 队列为空,等待
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
queue.remove();
lock.notifyAll(); // 唤醒等待的生产者线程
}
}
}, "Worker-2");
// 监控线程
Thread monitor = new Thread(() -> {
while (running) {
try {
Thread.sleep(1000);
System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
} catch (Exception e) {
break;
}
}
}, "Monitor");
monitor.start();
thread1.start();
thread2.start();
Thread.sleep(10000);
running = false;
}
}
E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=57754” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestBLOCKED2
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: BLOCKED, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: RUNNABLE
Worker1 status: BLOCKED, Worker2 status: WAITING
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: WAITING, Worker2 status: BLOCKED
Worker1 status: TERMINATED, Worker2 status: TERMINATEDProcess finished with exit code 0
WAITING
等待状态
1、调用了Object.wait()
2、Thread.join()
3、LockSupport.park
- Object.wait() 是让当前线程等待并释放锁,直到其他线程通知。
- Thread.join() 是让当前线程等待另一个线程结束。
Thread.join测试
模拟等待,Worker-2等待Worker-1线程执行完成。从结果来看,调用Thread.join当前线程状态由RUNNABLE变成WAITING当Worker-1结束后,线程状态也会变成 TERMINATED
package com.gyg.thread.demo1;
public class TestWAITING {
private static volatile boolean running = true;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (running) {
for (int i = 0; i < 1000; i++) Math.sin(i);
}
}, "Worker-1");
Thread thread2 = new Thread(() -> {
try {
thread1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "Worker-2");
// 监控线程
Thread monitor = new Thread(() -> {
while (running) {
try {
Thread.sleep(1000);
System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
} catch (Exception e) {
break;
}
}
}, "Monitor");
monitor.start();
thread1.start();
thread2.start();
Thread.sleep(10000);
running = false;
}
}
E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=63198” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATEDProcess finished with exit code 0
LockSupport演示
从结果可以看出调用LockSupport.park和Object.wait一样状态会变成WAITING,都需要解除等待的状态
LockSupport是JUC的包,基于信号量设计的,unpark可以在park之前,相当于先给你钥匙再给你锁。
package com.gyg.thread.demo1;
import java.util.concurrent.locks.LockSupport;
public class TestWAITING2 {
private static volatile boolean running = true;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (running) {
for (int i = 0; i < 1000; i++) Math.sin(i);
}
}, "Worker-1");
Thread thread2 = new Thread(() -> {
while (running) {
LockSupport.park();
}
}, "Worker-2");
// 监控线程
Thread monitor = new Thread(() -> {
while (running) {
try {
Thread.sleep(1000);
System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
} catch (Exception e) {
break;
}
}
}, "Monitor");
monitor.start();
thread1.start();
thread2.start();
Thread.sleep(10000);
running = false;
LockSupport.unpark(thread2);
}
}
E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=49846” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING2
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: RUNNABLE, Worker2 status: WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATEDProcess finished with exit code 0
TIMED_WAITING
线程处于有时间限制的等待状态
1、Thread.sleep
2、Object.wait 暂停
3、Thread.join 暂停
4、LockSupport.parkNanos
5、LockSupport.parkUntil
这里的方法,入参都可以传递时间参数
LockSupport.parkNanos演示
Worker-1 一直执行,Worker-2等待2S执行,从结果看Worker-2在等待时候的线程状态是 TIMED_WAITING,等待结束会变成RUNNABLE
package com.gyg.thread.demo1;
import java.util.concurrent.locks.LockSupport;
public class TestWAITING2 {
private static volatile boolean running = true;
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (running) {
for (int i = 0; i < 1000; i++) Math.sin(i);
}
}, "Worker-1");
Thread thread2 = new Thread(() -> {
while (running) {
LockSupport.parkNanos(2000000L);
for (int i = 0; i < 1000; i++) Math.cos(i);
}
}, "Worker-2");
// 监控线程
Thread monitor = new Thread(() -> {
while (running) {
try {
Thread.sleep(1000);
System.out.println("Worker1 status: " + thread1.getState() + ", Worker2 status: " + thread2.getState());
} catch (Exception e) {
break;
}
}
}, "Monitor");
monitor.start();
thread1.start();
thread2.start();
Thread.sleep(10000);
running = false;
LockSupport.unpark(thread2);
}
}
E:\java\jdk\jdk-21.0.8\bin\java.exe “-javaagent:E:\software\IntelliJ IDEA 2025.2.1\lib\idea_rt.jar=55839” -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath E:\java\project\demo\thread\target\classes com.gyg.thread.demo1.TestWAITING2
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: RUNNABLE
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: RUNNABLE, Worker2 status: TIMED_WAITING
Worker1 status: TERMINATED, Worker2 status: TERMINATEDProcess finished with exit code 0
尾声
如果解决有解决你的问题,点点赞,求个关注👍👍👍
醉后不知天在水,满船清梦压星河🤞🤞🤞,加油👏👏👏
更多推荐


所有评论(0)