Java中阻塞与等待的区别?

在 Java 编程中,阻塞(Blocking)等待(Waiting) 是两个常见的概念,特别是在多线程编程中。它们虽然看起来相似,但实际上有着本质的区别。

一、阻塞(Blocking)

阻塞是指线程在执行过程中被暂停,直到满足某些条件才能继续执行。这个暂停通常是由操作系统调度器控制的,常见的阻塞情况包括:

  1. I/O 阻塞

    • 当一个线程进行输入输出操作时(比如读写文件、网络通信等),如果数据没有准备好,线程会进入阻塞状态,直到数据准备就绪才能继续执行。
  2. 资源争用阻塞

    • 当一个线程需要获取一个资源(例如锁)而该资源被其他线程占用时,当前线程会被阻塞,直到资源被释放。

阻塞的线程会被操作系统从可运行队列中移除,直到条件满足再恢复执行。阻塞的线程不会消耗 CPU 资源。

阻塞的特点:
  • 阻塞通常是外部条件决定的,例如 I/O 操作、等待锁等。
  • 线程进入阻塞后,会被操作系统挂起,直到事件完成或外部条件满足。
  • 阻塞状态下的线程会被挂起,无法继续执行任务,直到外部事件(如 I/O 完成、锁释放等)发生。

二、等待(Waiting)

等待通常指线程进入一个等待状态,直到其他线程通过某种方式通知它继续执行。在 Java 中,线程可以通过调用 Object.wait()Thread.join()LockCondition.await() 等方法进入等待状态。通常情况下,线程会在这些方法中主动放弃 CPU 时间,等待某个条件满足时再继续执行。

  1. Object.wait()

    • 当前线程会进入一个等待队列,并放弃持有的锁。线程进入等待状态,直到其他线程调用 notify()notifyAll() 来唤醒它。
  2. Thread.join()

    • 如果一个线程调用 join() 方法,当前线程会等待被调用线程执行完毕,才能继续执行。
  3. Condition.await()

    • 在使用显式锁(如 ReentrantLock)时,可以通过 Condition 来实现等待和通知机制。
等待的特点:
  • 等待是由线程自身主动触发的,线程进入等待状态时,可能会在等待队列中等待某个条件(如事件发生、其他线程的操作等)。
  • 线程进入等待后,必须等待其他线程的通知才能继续执行。通常需要其他线程调用 notify()notifyAll() 或其他方式来唤醒。
  • 等待的线程会放弃 CPU 时间,直到被通知或者条件满足。

三、阻塞与等待的对比

特性阻塞(Blocking)等待(Waiting)
发生的原因外部条件导致,如 I/O 操作、资源争用等线程主动进入等待,直到被通知或条件满足
线程状态线程会进入阻塞队列,无法继续执行线程进入等待队列,必须等待其他线程通知
是否主动放弃 CPU线程会被挂起,外部条件满足后恢复执行线程主动放弃 CPU,直到被唤醒或条件满足
典型方法Thread.sleep()、I/O 操作、锁等待等Object.wait()Thread.join()Condition.await()
需要通知不需要其他线程通知需要其他线程通知,如 notify()notifyAll()

四、总结

  • 阻塞是指线程由于外部条件(如等待 I/O 操作、获取资源等)无法继续执行,线程会被挂起,直到外部条件满足。
  • 等待是指线程主动进入等待状态,通常是因为它在等待其他线程的通知或某个条件的变化。

这两个概念的关键区别在于 谁控制线程的暂停:阻塞通常是由外部事件(如 I/O 操作)控制的,而等待是由线程自身决定并等待其他线程的唤醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值