我最近一直在学习Java中的多线程概念。我有一些疑问,无法通过在StackOverflow上查找相关线程来解决。对于以下问题,我找不到令人满意的答案:
wait()方法使线程等待直到获得锁。而wait(long timeout)方法使线程等待'timeout'否。毫秒,如果仍然无法获得锁定,则返回可运行状态。但是要真正进入运行状态,它却需要锁。那么,wait(长超时)方法的意义何在?但是,线程在等待状态时会释放其获取的锁。因此,差异甚至不是它获得的资源。如果线程保持等待状态或可运行状态,会有什么区别?与wait()方法相比,wait(long timeout)有什么优势?
synchonized关键字或块可在调用该方法或块的对象上提供锁定。它导致另一个试图获取同一实例上的锁的线程等待。但是对于ReentrantLock,锁是在哪个对象上获得的?试图获取其锁定的线程正在等待?
ReentrantLock如何避免死锁?假设有两种方法m1和m2。两者都需要获得一个锁。 m1正在呼叫m2,而m2正在呼叫m1。在这种情况下,如何使用ReentrantLock避免死锁?也许我们可以使用tryLock()并为无法获取锁的线程提供替代操作。但是可能的替代操作是什么?如果线程必须需要锁才能工作怎么办?
我发现使用ReentrantLock可以多次获取锁。但是为什么我们必须多次获得锁?我已经阅读了有关此问题的理论答案,但无法真正理解。如果您可以使用清晰的示例代码进行演示,将很有帮助。
最佳答案
为什么我们需要多次获取锁?
显然,您不需要。但是,应用程序“偶然”执行此操作并不罕见。例如:
public void binaryOperation(Operand op1, Operand op2) {
synchronized (op1) {
synchronized (op2) {
// do something that needs the locks
}
}
}
// now call passing the same object for both operands
Operand op = ...
binaryOperation(op, op);
在此示例中,
op
对象实际上将被锁定两次。如果不重入原始锁,则可能会失败(或死锁)。现在,我们可以修复
binaryOperation
方法不这样做,但这会使代码复杂得多。ReentrantLock
可能发生相同的情况。问题1
但是要真正进入运行状态,它却需要锁。那么,wait(长超时)方法的意义何在?
这是关于
Object::wait
。 ReentrantLock
API不支持此功能。 (请注意:您可以在wait
对象上使用notify
和ReentrantLock
,但是仅当您将其视为原始锁时才行。这不是一个好主意!)wait
正在等待通知,并且timeout
表示呼叫者准备等待通知的时间。正如javadoc所说:“导致当前线程等待,直到另一个线程为此对象调用
notify()
方法或notifyAll()
方法,或者经过指定的时间。使用
wait()
和wait(timeout)
,由调用者检查是否确实满足了预期要“通知”的条件。 (请参阅有关“虚假唤醒”的注释以及示例代码。)与wait()方法相比,wait(long timeout)有什么优势?
简而言之,它使您可以选择仅在有限的时间内等待通知。如果这没有用,请不要使用它。
问题2。
但是在
ReentrantLock
的情况下,在哪个对象上获得了锁?严格来说,它是锁本身。锁的实际含义取决于您编写类的方式。但这与原始互斥锁完全相同。
锁定Java不会在不持有锁定的情况下访问和/或更新某些共享状态而导致某些行为异常。程序员必须正确执行此操作。
试图获取其锁定的线程正在等待?
是。
问题3。
ReentrantLock如何避免死锁?
通常情况并非如此。
在可重入锁定的情况下(即,在线程尝试持有锁A的同时尝试获取锁A的情况),
ReentrantLock
实现会注意到持有锁的线程是获取锁的线程。计数器增加,因此实现知道该锁必须释放两次。在这种情况下,如何使用ReentrantLock避免死锁?也许我们可以使用tryLock()并为无法获取锁的线程提供替代操作。
那是一种方法。
但是可能的替代操作是什么?
确保所有线程以相同顺序获取锁。 (当线程尝试以不同的顺序获取两个或多个线程时,将发生死锁。)
如果
tryLock
在持有其他锁时失败,请释放该锁,稍等片刻,然后重试。如果线程必须需要锁才能工作怎么办?
然后设计逻辑,避免死锁。见上面的替代品!
问题4。
但是为什么我们必须多次获得锁?
如上所述,您通常不需要。但是
ReentrantLock
的要点是,您不必担心由于某种原因而最终两次获得锁的情况。关于java - Reentrantlock-为什么我们需要多次获取锁?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57440851/