根据 Oracle 官方文档定义:
:::info
Blocked : 这个状态下,线程被阻塞等待获取监视器锁🔐。Waiting : 这个状态下,线程无限期等待其他线程执行一个特定动作。
:::
官方的定义言简意赅,但是很难理解,下面通俗地解释下两者的区别。
当线程在一个对象上调用 wait() 时,就会进入 waiting 状态。一旦线程进入 waiting 状态,
将一直等待直到其他线程调用之前对象的 notify() 或 notifyAll() .
一旦线程被通知,它不会直接进入 runnable 状态,仍然不可运行。因为可能其他线程也被通知了
(调用的 notifyAll() ),或者第一个线程还未执行完同步代码块(线程调用完对象锁的 notify() 或 notifyAll() ,并不会马上释放锁,会继续运行完同步块),因此线程将继续阻塞,进入 Blocked 状态。
无论何时,只要线程试图获取获取对象锁,并且这个锁已经被其他线程持有,这个线程就会进入 Blocked 状态。
一旦其他线程执行完同步代码块,并且如果这个线程竞争到了锁,那么它就进入 Runnable 状态, Runnable
状态包含正在运行 Running 和等待获取 CPU 时间片两种情况。
:::info
Waiting 状态的线程无法直接进入 Runnable 状态,必须先被 notify()、notifyAll() 进入 Blocked 状态去竞争锁,才有可能进入 Runnable 状态。
Waiting 状态 wait 的并不是锁,而是其他线程的 nofity ; Blocked 状态的线程是因为竞争的锁被其他线程持有而被 block .
:::
