面试tips----并发--BLOCKED和WAITING两个状态
摘要: Java线程中,BLOCKED与WAITING状态的核心区别在于等待机制: BLOCKED:线程被动等待获取synchronized锁(如锁被占用),需等待锁释放后才能继续执行(如线程B等待线程A释放锁)。 WAITING:线程主动放弃执行权(通过wait()或park()),需其他线程显式唤醒(如notify())。 比喻:BLOCKED像排队等进屋,WAITING像进屋后坐下等人叫醒。
🔹 Java 线程状态回顾
Java 里线程状态(
Thread.State枚举)常见有:
NEW:新建,刚创建还没启动
RUNNABLE:可运行(可能在运行,可能在就绪队列等 CPU)
BLOCKED:阻塞,等待 获取对象锁
WAITING:无限期等待,等待 其他线程显式唤醒
TIMED_WAITING:有时限等待
TERMINATED:已结束
🔸 BLOCKED 状态
定义:线程正在尝试进入一个 synchronized 修饰的代码块或方法,但对象的 monitor 锁 已经被其他线程占用,所以它只能在 阻塞队列里等。
👉 关键词:等锁(monitor)
例子:
class Test { public synchronized void print() { System.out.println(Thread.currentThread().getName() + " 获取到锁"); try { Thread.sleep(5000); } catch (InterruptedException e) {} } } public class Main { public static void main(String[] args) { Test test = new Test(); new Thread(test::print, "线程A").start(); new Thread(test::print, "线程B").start(); } }
线程A先启动,进入
print(),拿到锁,休眠5秒。线程B也调用
print(),但是锁还在A手里,B就会进入 BLOCKED 状态。
(此时B不是在等待唤醒,而是等着 锁释放,一旦A释放锁,B就能继续执行。)
🔸 WAITING 状态
定义:线程主动进入等待,等待 别的线程显式唤醒,比如
Object.wait()、LockSupport.park()。👉 关键词:等别人通知(notify/notifyAll/unpark)
例子:
public class WaitingExample { private static final Object lock = new Object(); public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { synchronized (lock) { try { System.out.println("线程A进入等待状态"); lock.wait(); // 无限期等待 System.out.println("线程A被唤醒"); } catch (InterruptedException e) {} } }); t1.start(); Thread.sleep(2000); synchronized (lock) { System.out.println("主线程唤醒A"); lock.notify(); } } }
t1调用lock.wait()→ 进入 WAITING。主线程调用
lock.notify()→ 唤醒t1,然后t1再去竞争锁。如果没人唤醒,线程会一直卡在 WAITING 状态。
🔹 区别总结
状态 触发条件 解除方式 比喻 BLOCKED 等待进入 synchronized,锁被别人持有等别人 释放锁 门口排队进屋,屋里有人,不开门 WAITING 调用 wait()/park(),自己放弃运行机会等别人 叫醒 ( notify/unpark)进屋后自己坐下等别人喊起身
✅ 所以一句话总结:
BLOCKED 是被动的卡在门口等锁;
WAITING 是主动的坐下等别人通知。
更多推荐
所有评论(0)