线程阻塞与等待的区别
线程阻塞与等待的区别
- 简单来说,线程阻塞是被动发生的,当满足线程所需要的条件时线程会自动恢复执行;而线程等待是主动发生的,线程必须等待其他线程的通知才能继续执行。
1. 阻塞(Blocking)
-
线程阻塞是指线程因为某些原因无法继续执行,进入阻塞状态。常见的阻塞情况包括:
- I/O 阻塞:执行I/O操作时数据没有准备好。
- 资源争用阻塞:多个线程获取一个资源而该资源被其他线程占用。
-
阻塞的线程会被操作系统从可运行队列中移除,直到条件满足再恢复执行。阻塞的线程不会消耗 CPU 资源。
-
阻塞的特点:
- 阻塞通常是外部条件决定的,例如I/O操作、等待锁等。
- 线程进入阻塞后,会被操作系统挂起,直到事件完成或外部条件满足。
- 阻塞状态下的线程会被挂起,无法继续执行任务,直到外部事件(如 I/O 完成、锁释放等)发生。
2. 等待(Waiting)
-
等待通常指线程进入一个等待状态,直到其他线程通过某种方式通知它继续执行。线程进入等待状态的常见方式包括:
-
使用
Object.wait()方法:线程调用该方法后进入等待状态,直到被其他线程调用notify()或notifyAll()方法唤醒。 -
使用
Thread.join()方法等待另一个线程完成。 -
使用
Condition.await()方法:在使用显示锁(如ReentrantLock)时,可以通过Condation来实现等待和通知机制。 -
等待的特点:
- 等待是由线程自身主动触发的。
- 线程进入等待后,必须等待其他线程的通知才能继续执行。
3. 区别
| 特性 | 阻塞(Blocking) | 等待(Waiting) |
|---|---|---|
| 发生的原因 | 外部条件导致,如I/O操作、资源争用等 | 线程主动进入等待,直到被通知或条件满足 |
| 线程状态 | 线程会进入阻塞队列,无法继续执行 | 线程进入等待队列,必须等待其他线程通知 |
| 是否主动放弃 | CPU线程会被挂起,外部条件满足后恢复执行 | 线程主动放弃CPU,直到被唤醒或条件满足 |
| 典型方法 | Thread.sleep()、I/O 操作、锁等待等 |
Object.wait()、Thread.join()、Condition.await() |
| 需要通知 | 不需要其他线程通知 | 需要其他线程通知,如notify()或notifyAll() |
