我读过很多关于线程状态的文档,其中一些说有两种不同的状态:阻塞(同步之前)和等待(如果调用等待),还有一些说只有一种状态:等待。此外,一些文档告诉你应该为每个 wait() 调用 notify() ,如果你不这样做,那么即使监视器被解锁,线程 waiting() 也永远不会有资格执行。
4 回答
从你最后一句话,我看到你并不完全理解synchronized
and wait()
/之间的区别notify()
。
基本上,监视器有lock和condition。这几乎是正交的概念。
当线程进入一个
synchronized
块时,它会获得一个锁。当线程离开该块时,它会释放锁。只有一个线程可以锁定特定的监视器。当有锁的线程调用
wait()
时,它会释放锁并开始等待它的条件。当有锁的线程调用notify()
时,等待条件的线程之一(在 的情况下为所有线程notifyAll()
)有资格执行(并开始等待获取锁,因为通知线程仍然拥有它)。
因此,等待获取锁 (Thread.State.BLOCKED) 和等待监视器状态 (Thread.State.WAITING) 是不同且独立的状态。
如果你看一下类,这种行为会变得更加清晰Lock
——它实现了与块相同的同步原语synchronized
(带有一些扩展),但在锁和条件之间提供了明显的区别。
当一个线程调用
Object.wait
方法时,它会释放这个获取的监视器并进入WAITING
(或者TIMED_WAITING
如果我们调用等待方法的超时版本)状态。现在,当线程notify()
通过调用或notifyAll()
调用同一对象得到通知时,线程的等待状态结束,线程开始尝试重新获得它在等待调用时获得的所有监视器。有一次可能有几个线程试图重新获得(或者可能是第一次获得)他们的监视器。如果多个线程尝试获取特定对象的监视器,则只有一个线程(由JVM
调度程序选择)被授予监视器,所有其他线程都进入BLOCKED
状态。
有两种不同的状态BLOCKED 和 WAITING。
如果没有人通知(或打断)您,则永远等待的部分是正确的。
在 Java 的观点(Thread.State)中,有两种不同的状态:BLOCKED 和 WAITING。当一个线程在一个对象上同步时,它处于 BLOCKED 状态。线程执行 wait 后,处于 WAITING 状态。
在 Linux 平台上,Java 线程是 OS 原生线程。BLOCKED 和 WAITING 状态的 OS 线程状态都是可中断睡眠。使用 ps 检查时,BLOCKED 和 WAITING 线程的状态都是“Sl+”。