线程状态,BLOCKED和WAITING有什么区别
                           
天天向上
发布: 2025-07-20 11:27:43

原创
799 人浏览过

线程状态中,BLOCKEDWAITING 是两种不同的阻塞状态,它们的区别主要体现在线程阻塞的原因和等待方式上。下面帮你详细解析这两者的区别和应用场景。


一、线程状态简述

Java 中线程的状态由 Thread.State 枚举表示,主要状态包括:

  • NEW:新建,线程还未启动
  • RUNNABLE:可运行,线程正在运行或等待 CPU 时间片
  • BLOCKED:阻塞,等待获取监视器锁(monitor lock)
  • WAITING:无限期等待,等待另一个线程显式通知
  • TIMED_WAITING:限时等待,等待指定时间后自动唤醒
  • TERMINATED:终止,线程执行完成或退出

二、BLOCKED 和 WAITING 的详细区别

特性BLOCKEDWAITING
等待原因等待进入同步块或方法,争抢对象锁等待其他线程显式通知(如 wait()join()
触发方式线程尝试获得对象锁失败进入阻塞队列线程调用无超时等待方法进入等待状态
恢复条件获得锁后恢复运行被其他线程 notify()notifyAll() 唤醒,或调用 interrupt()
等待时间直到获得锁,时间不确定无限等待,直到收到通知或中断
典型场景进入 synchronized 代码块或方法时,锁被占用调用 Object.wait()Thread.join() 等等待线程操作

三、具体示例对比

1. BLOCKED 示例

public class BlockedDemo {
    private final Object lock = new Object();

    public void method() {
        synchronized (lock) {
            try {
                Thread.sleep(5000); // 模拟占用锁5秒
            } catch (InterruptedException e) {}
        }
    }

    public static void main(String[] args) {
        BlockedDemo demo = new BlockedDemo();

        new Thread(() -> demo.method(), "线程-1").start();

        new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " 尝试获取锁");
            demo.method();  // 这里如果锁被占用,线程会进入 BLOCKED 状态
        }, "线程-2").start();
    }
}
  • 线程-2 在锁被 线程-1 占用时进入 BLOCKED 状态,等待锁释放。

2. WAITING 示例

public class WaitingDemo {
    public static void main(String[] args) throws InterruptedException {
        Object lock = new Object();

        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("线程等待通知...");
                    lock.wait();  // 进入 WAITING 状态,等待通知
                    System.out.println("线程被唤醒");
                } catch (InterruptedException e) {
                    System.out.println("线程被中断");
                }
            }
        });

        t1.start();

        Thread.sleep(2000);

        synchronized (lock) {
            lock.notify();  // 唤醒等待线程
        }
    }
}
  • 线程调用 wait() 后进入 WAITING 状态,等待其他线程调用 notify() 唤醒。

四、状态转换流程示意

RUNNABLE 
  |
  |(尝试进入 synchronized 代码块,锁被占用)
  ↓
BLOCKED (等待锁)
  |
  |(获得锁)
  ↓
RUNNABLE

---

RUNNABLE
  |
  |(调用 wait() 或 join() 等无超时等待方法)
  ↓
WAITING
  |
  |(其他线程调用 notify()/interrupt())
  ↓
RUNNABLE

五、总结对比

方面BLOCKEDWAITING
阻塞原因竞争对象锁等待显式通知
是否依赖锁
等待时长不定,直到获得锁不定,直到通知或中断
进入方式尝试进入 synchronized 块时失败调用 wait()join()
唤醒方式获得锁即恢复其他线程调用 notify()/interrupt()
典型使用场景同步锁竞争线程间通信和协调

六、参考资料


更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *