🔹 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 是主动的坐下等别人通知。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐