当前位置: 首页 > 知识库问答 >
问题:

在调用其条件时,重入锁是否被释放。

祁建明
2023-03-14

我有以下代码:

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调用synchronizer.signalAll()以向线程1发送信号。我的问题是线程2如何通过调用

lock.lock();

打电话之前

done.signallAll();

锁最初是由线程 1 获取的?

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

等待可重入锁中的条件

答案是:

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

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

答案还指出:

注意:它们不会完全释放它,如果进行堆栈跟踪,可能会有多个线程同时持有锁,但最多只能有一个线程在运行(其余线程将等待)

然而,条件的文件。await()声明:

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

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

共有1个答案

崔涵亮
2023-03-14
    < li >线程1 (T1)将在#await() lock.lock()调用时获取锁 < li>T1将在#await() done.await()时释放锁。T1将停留,直到发出信号或中断或“虚假唤醒”* < li>T2将在#signallAll() lock.lock处获得锁 < li>T2将发出唤醒信号# signal all()done . signal all < li>T2将释放lock # signal all()lock . unlock < li>T1将在#await() done.await()唤醒 < li>T1将获取锁#await() done.await() < li>T1将释放lock #await() lock.unlock()

T1可以在运行T2的任何时候被“虚假唤醒”。但这将发生在完成.等待呼叫。除非关联的锁被解锁并且其他释放条件不正确(必须发出信号或中断线程),否则永远不会将控制权恢复到调用方代码。

 类似资料:
  • 问题内容: 以下代码取自的JavaDoc: 想象一下, 消费者 和 生产者这 两个线程,一个正在使用,一个在单个实例上。 假设 消费者 先运行,然后锁定,然后循环运行。 现在, 生产者 如何才能通过锁定已由 消费者 持有的来进入方法? 我在这里想念什么?是线程正在等待其条件之一时“临时释放”吗?锁的重新 进入 到底意味着什么? 问题答案: 双方并允许一个线程等待的时候,另一个线程可以获得锁放弃锁。

  • 问题内容: 我的Java程序想要读取一个文件,该文件可以被另一个写入该文件的程序锁定。我需要检查文件是否已锁定,如果已锁定,请等待它释放。我该如何实现? Java程序在Windows 2000服务器上运行。 问题答案: 在带有Sun JVM的Windows下,尽管JavaDoc保留了相当模糊的可靠性(取决于系统),但FileLocks应该可以正常工作。 但是,如果您只需要在Java程序中识别出 其

  • 每个java对象都有一个内置锁。因此,如果许多线程中的一个想要调用同步方法,它会获取对象的锁。 所以我们假设我们有一个对象和两个线程,t1和t2。 t1线程请求对象的锁来调用同步方法object.methodA()。同时t2请求对象的锁来调用同步方法object.methodB()。 这能做到吗? 两个线程是否可以获取两种不同方法的锁?(想象一个理想的场景,其中methodA()和methodB(

  • 我对std::condition_变量的用法有点困惑。我知道在调用。我找不到的是,在调用或之前,我是否还应该获取一个唯一的锁。 cppreference.com的例子是相互矛盾的。例如,notify_one页面给出了这个例子: 在这里,锁不是为第一个获取的,而是为第二个获取的。查看其他页面上的示例,我看到了不同的东西,大多数情况下没有获得锁。 在调用之前,我可以选择自己锁定互斥锁吗?我为什么选择锁

  • React是否在每次调用时重新呈现所有组件和子组件? 如果是,为什么?我认为这个想法是,当状态改变时,只会根据需要提供少量的反应。 我希望只有在数据发生更改时才会出现呈现。 下面是示例的代码,作为JS Fiddle和嵌入的代码片段:

  • 您可以在下面的问题中看到:(liquibase-lock-reasons)当Liquibase操作中断时客户端Liquibase锁定,使Liquibase处于锁定状态。 我想知道是否有一种方法可以配置Liquibase,使其从列中的日期和时间自动检测这种情况。我想如果你已经拿着锁一个小时了--你应该把它叫做过期锁。