在Java中如果一个线程,t2
,尝试从synchronized获取锁,该锁当前正被另一个线程使用,t1
,然后t2
将从可运行状态切换为阻塞状态。正确的? ReentrantLock
怎么样?是吗?
如果线程t1
完成使用锁后,t2
然后自动切换回可运行状态还是需要使用 notifyAll()
? ReentrantLock
怎么样?无条件使用。如果您没有使用条件,您如何通知线程 t2
它应该切换回可运行状态吗?在没有条件的情况下使用可重入锁是否明智,甚至可能?
如果这个问题已经得到解答(我找不到),如果您能将其链接到我,我将不胜感激。
最佳答案
听起来您混淆了阻塞状态和等待状态。阻塞意味着线程正在尝试获取锁但无法获取,因此被卡住。等待意味着线程处于 hibernate 状态;它会一直挂起,直到收到通知,或者直到它从等待中返回(如果使用超时值调用,则超时,或者虚假唤醒)。
一旦锁可用,操作系统调度程序就必须决定哪个阻塞线程获得它。它选择获取锁的线程变得可运行。
因此,通知适用于等待线程,而不是阻塞线程。拥有锁但发现它无法前进(它检测到它正在等待的条件不成立)的线程可以对该锁调用 wait,释放锁并进入 hibernate 状态。您可以使用notify 告诉调度程序唤醒任何正在等待该锁的线程。一旦线程被唤醒,它必须重新获取之前释放的锁,然后才能退出 wait 方法。
ReentrantLock 的基本行为类似于内在锁,只不过可重入锁可以有多个条件。请记住,ReentrantLock 有其自己单独的调用方法(等待和信号而不是等待和通知)。当您希望线程等待并获得通知时,您可以将条件与 ReentrantLock 一起使用,并使用不同的条件,以便线程仅在与其相关的条件下等待。
关于java - 线程、锁和条件的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41450644/