繁体   English   中英

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

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

我有以下代码:

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
        }
    }
}

假设线程1调用synchornizer.await()并通过

lock.lock();

并在

done.await();

然后另一个线程2调用syncnizer.signalAll()以便向线程1发出信号。我的问题是,线程2如何能够通过调用来获取锁

lock.lock();

打电话之前

done.signallAll();

线程1最初何时获得了锁?

我在这里发现了同样的问题:

在重入锁中等待条件

答案是:

锁定和同步都暂时允许其他人在等待时获得锁定。 要停止等待,线程必须重新获取锁。

我试图理解这是否意味着如果线程1未调用done.await(),线程2将无法获取锁?

答案还指出:

注意:它们没有完全释放它,并且如果您执行堆栈跟踪,则可能有多个线程似乎同时持有该锁,但其中最多一个线程将在运行(其余线程将在等待)

但是Condition.await()的文档指出:

与此条件相关联的锁被原子释放

那么,锁是否被释放?“他们没有完全释放它”是什么意思?

  1. 线程1(T1)将在#await()lock.lock()调用中获取锁
  2. T1将在#await()done.await()处释放锁定。 T1将停放,直到发出信号,中断或“虚假唤醒” *
  3. T2将在#signallAll()lock.lock处获取锁定
  4. T2将发出唤醒信号#signallAll()done.signalAll
  5. T2将释放锁#signallAll()lock.unlock
  6. T1将在#await()完成时醒来。await()
  7. T1将获取锁#await()done.await()
  8. T1将释放锁#await()lock.unlock()

T1在运行T2的任何时候都可能被“虚假唤醒”。 但这将在done.await调用内发生。 除非将相关联的锁解锁并且其他释放条件不正确(线程必须发出信号或中断),否则控制永远不会退回到调用者代码。

暂无
暂无

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

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