简体   繁体   English

调用condition.await时是否释放可重入锁?

[英]Is a reentrant lock released when calling its condition.await?

I have the following code: 我有以下代码:

public class Synchronizer {

    private final Lock lock = new ReentrantLock();
    private final Condition done = lock.newCondition();
    private boolean isDone = false;

    private void signalAll() {

        lock.lock(); // MUST lock!
        try {
            isDone = true; // To help the await method ascertain that it has not waken up 'spuriously'
            done.signalAll();
        }
        finally {
            lock.unlock(); // Make sure to unlock even in case of an exception
        }
    }

    public void await() {

        lock.lock(); // MUST lock!
        try {
            while (!isDone) { // Ascertain that this is not a 'spurious wake-up'
                done.await();
            }
        }
        finally {
            isDone = false; // for next time
            lock.unlock(); // Make sure to unlock even in case of an exception
        }
    }
}

Suppose thread 1 calls synchornizer.await() and acquires the lock via the 假设线程1调用synchornizer.await()并通过

lock.lock();

and blocks on the 并在

done.await();

Then another thread 2 calls synchronizer.signalAll() in order to signal thread 1. My question is how is thread 2 ever able to acquire the lock by calling 然后另一个线程2调用syncnizer.signalAll()以便向线程1发出信号。我的问题是,线程2如何能够通过调用来获取锁

lock.lock();

before calling 打电话之前

done.signallAll();

when the lock was initially acquired by thread 1? 线程1最初何时获得了锁?

I found the same question here: 我在这里发现了同样的问题:

Waiting on a condition in a reentrant lock 在重入锁中等待条件

The answer says: 答案是:

Both Lock and synchronized temporarily allow others to obtain the lock when they are waiting. 锁定和同步都暂时允许其他人在等待时获得锁定。 To stop waiting, a thread have to re-acquire the lock. 要停止等待,线程必须重新获取锁。

I am trying to understand does this mean that thread 2 would not be able to acquire the lock if thread 1 did not call done.await()? 我试图理解这是否意味着如果线程1未调用done.await(),线程2将无法获取锁?

Also the answer states that: 答案还指出:

Note: They don't release it fully and if you take a stack trace you can have multiple threads which appear to be holding the lock at once, but at most one of them will be running (the rest will be waiting) 注意:它们没有完全释放它,并且如果您执行堆栈跟踪,则可能有多个线程似乎同时持有该锁,但其中最多一个线程将在运行(其余线程将在等待)

Yet the documentation for Condition.await() states that: 但是Condition.await()的文档指出:

The lock associated with this Condition is atomically released 与此条件相关联的锁被原子释放

So is the lock released or not and what "They don't release it fully" mean? 那么,锁是否被释放?“他们没有完全释放它”是什么意思?

  1. Thread 1 (T1) will acquire lock at #await() lock.lock() call 线程1(T1)将在#await()lock.lock()调用中获取锁
  2. T1 will release lock at #await() done.await(). T1将在#await()done.await()处释放锁定。 T1 will park untill signaled or interupted or "spurious waked"* T1将停放,直到发出信号,中断或“虚假唤醒” *
  3. T2 will acquire lock at #signallAll() lock.lock T2将在#signallAll()lock.lock处获取锁定
  4. T2 will signal waking up #signallAll() done.signalAll T2将发出唤醒信号#signallAll()done.signalAll
  5. T2 will release lock #signallAll() lock.unlock T2将释放锁#signallAll()lock.unlock
  6. T1 will wake up at #await() done.await() T1将在#await()完成时醒来。await()
  7. T1 will acquire lock #await() done.await() T1将获取锁#await()done.await()
  8. T1 will release lock #await() lock.unlock() T1将释放锁#await()lock.unlock()

T1 could be "spurious waked" at any point of running T2. T1在运行T2的任何时候都可能被“虚假唤醒”。 But this will happen within done.await call. 但这将在done.await调用内发生。 Control will never be retured to caller code unless associated lock is unlocked and other conditions for releasing are not right (thread must be signaled or interupted). 除非将相关联的锁解锁并且其他释放条件不正确(线程必须发出信号或中断),否则控制永远不会退回到调用者代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM