java - 线程、锁和条件的状态

标签 java multithreading locking synchronized reentrantlock

在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/

相关文章:

java - 如何安全地将昂贵的数据库操作带到同步块(synchronized block)之外以避免争用

c - 多次调用 pthread_join 如何工作?

c# - 如何使用 Jet OLEDB 打开 CSV 或 XLS 文件并获得表锁定?

java - 如何在 Mac OS Mountain Lion 上的 Java 1.7 中安装 JCE?

c# - 如何 async-await "save threads"?

java - 解析问题和数字 "doing math"(一个简单的 java 计算器)

java - 我们是否能够使用 java 将文件夹或目录锁定特定的时间段?

java - 如何使用 StampedLock 乐观锁定?(我无法理解 java 文档中的代码示例)

java - 删除父项将子值设置为 NULL 而不删除它们

Java/Groovy - GroovyClassLoader 中的内存泄漏