【问题标题】:When is monitor released in java什么时候在java中发布监视器
【发布时间】:2012-03-30 13:52:19
【问题描述】:

如果我有代码:

ReentrantLock lock = new ReentrantLock();
Condition waiting = lock.newCondition();

线程 1:

    value = default;
    lock.lock();
    try {
        waiting.await(new Long(timeout).longValue(), TimeUnit.SECONDS);
    } catch (InterruptedException e) {

        } finally {
            lock.unlock();
        }

线程 2:

  lock.lock();
  //set value
  waiting.signalAll();
  lock.unlock();    

我是否正确,因为当调用 await 时释放了锁上的监视器,允许事件驱动线程 2 在需要时运行?如果线程 2 恰好运行,线程 1 何时能够在 signalAll() 或 lock.unlock() 时恢复?如果线程 2 发出唤醒信号,但仍然有锁,那它是如何工作的??

【问题讨论】:

    标签: java concurrency


    【解决方案1】:

    调用await 时实际上释放了锁。当signalAll被调用时,没有等待线程会被唤醒,直到信号线程unlocks

    但是,区分 Java 对象监视器和 Java 锁很重要。它们是独立的结构,实际上 ReentrantLock/Condition 本身可以是与您正在使用的上下文不同的监视器(例如,如果您调用 wait 而不是 await,您会得到明显的 IllegalMonitorStateException)。

    【讨论】:

    • 感谢您的信息,我想我在旧/新方式之间混淆了一些术语 - 但它看起来是相同的基本概念,但一个是使用监视器和其他锁/条件.
    • 没错,这是两种不同的机制。无论如何,如果您使用监视器,您应该在 synchronized(monitor) 块中编写代码,这样就不会出现 IllegalMonitorStateException。
    • @WillDen 你说得对,基本思想是一样的,synchronizedReentrantLock 语义相同。
    • 为什么设计await释放锁而signal不释放?这让我很困惑。
    • @Jaskey 因为signalsignalAll 不会挂起线程。当您调用signal 时,您是在告诉JVM,当我释放锁(应该很快)时,让另一个等待进入的线程。 await 将暂停线程,因此您没有机会释放锁(这是有道理的)。
    猜你喜欢
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2011-01-04
    • 2011-03-22
    • 2019-05-15
    相关资源
    最近更新 更多