Java Reentrantlock-为什么我们需要多次获取锁?
我最近一直在学习java中的多线程概念。我有一些疑问没有通过查找StackOverflow上的相关线程来解决。我无法找到以下问题的满意答案:Java Reentrantlock-为什么我们需要多次获取锁?,java,multithreading,concurrency,reentrantlock,Java,Multithreading,Concurrency,Reentrantlock,我最近一直在学习java中的多线程概念。我有一些疑问没有通过查找StackOverflow上的相关线程来解决。我无法找到以下问题的满意答案: wait()方法使线程等待直到获得锁。然而,wait(longtimeout)方法使线程等待'timeout'毫秒数,如果它仍然没有获得锁,则返回到runnable状态。但要真正进入运行状态,它需要锁。那么等待(长超时)方法的要点是什么?然而,当线程处于等待状态时,它会释放它获取的锁。因此,差异甚至不在于它所获得的资源。如果线程处于等待状态或可运行状态,会
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 但要真正进入运行状态,它需要锁。那么等待(长超时)方法的要点是什么 这是关于
Object::wait
。ReentrantLock
API不支持此操作。(注意:您可以对ReentrantLock
对象使用wait
和notify
,但前提是将其视为基本锁。这不是一个好主意!)
wait
正在等待通知,timeout
表示调用方准备等待通知的时间。正如政府所说:
使当前线程等待,直到另一个线程调用此对象的notify()
方法或notifyAll()
方法,或者经过指定的时间
对于wait()
和wait(timeout)
,由调用方检查其期望“通知”的条件是否实际满足。(请参阅关于“虚假唤醒”的注释……以及示例代码。)
与wait()方法相比,wait(长超时)有什么优势
简单地说,它为您提供了只等待有限时间的通知的选项。如果这是没有用的,不要使用它
问题2 但是在
可重入锁
的情况下,在哪个对象上获取锁
严格地说,这是锁本身。锁的实际含义将取决于如何编写类。但这与原始互斥体完全相同
Java中的锁定不会阻止一些行为不端的代码在不持有锁的情况下访问和/或更新某些共享状态。这取决于程序员如何正确地完成它
试图获取其锁的线程被设置为等待
对
问题3 ReentrantLock如何避免死锁 一般来说,它不是 在可重入锁定的情况下(即线程在持有锁a的同时尝试获取锁a的情况下),
ReentrantLock
实现会注意到持有锁的线程就是获取锁的线程。计数器递增,以便实现知道锁必须释放两次
在这种情况下,如何使用ReentrantLock避免死锁?可能我们可以使用tryLock()并为无法获取锁的线程提供备用操作
这是一种方法
但可能的替代行动是什么
tryLock
在持有其他锁时失败,请释放锁,稍等片刻,然后重试问题4 但为什么我们必须多次获得锁 如上所述,您通常不会。但是,
ReentrantLock
的要点是,如果您最终两次获得锁,您不必担心。。。不管什么原因