当前位置: 首页 > 面试题库 >

在可重入锁中等待条件

赏星河
2023-03-14
问题内容

以下代码取自的JavaDocCondition

class BoundedBuffer {
  final Lock lock = new ReentrantLock();
  final Condition notFull  = lock.newCondition(); 
  final Condition notEmpty = lock.newCondition();

  final Object[] items = new Object[100];
  int putptr, takeptr, count;

  public void put(Object x) throws InterruptedException {
    lock.lock();
    try {
      while (count == items.length) 
        notFull.await();
      items[putptr] = x; 
      if (++putptr == items.length) putptr = 0;
      ++count;
      notEmpty.signal();
    } finally {
      lock.unlock();
    }
  }

  public Object take() throws InterruptedException {
    lock.lock();
    try {
      while (count == 0) 
        notEmpty.await();
      Object x = items[takeptr]; 
      if (++takeptr == items.length) takeptr = 0;
      --count;
      notFull.signal();
      return x;
    } finally {
      lock.unlock();
    }
  } 
}

想象一下, 消费者生产者这 两个线程,一个正在使用take,一个put在单个实例上BoundedBuffer

假设 消费者 先运行take(),然后锁定,lock然后循环运行notEmpty.await();

现在, 生产者 如何才能put()通过锁定lock已由 消费者 持有的来进入方法?

我在这里想念什么?是lock线程正在等待其条件之一时“临时释放”吗?锁的重新 进入 到底意味着什么?


问题答案:

双方Locksynchronized允许一个线程等待的时候,另一个线程可以获得锁放弃锁。要停止等待,线程必须重新获取锁。

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

从Condition.await()

与此条件相关联的锁被原子释放,并且出于线程调度目的,当前线程被禁用,并且处于休眠状态,直到发生以下四种情况之一:

  • 其他一些线程为此条件调用signal()方法,并且当前线程恰好被选择为要唤醒的线程;要么
  • 其他一些线程为此条件调用signalAll()方法。要么
  • 其他一些线程中断当前线程,并支持中断线程挂起;要么
  • 发生“虚假唤醒”。

在所有情况下,在此方法可以返回之前,当前线程必须重新获取与此条件关联的锁。当线程返回时,可以保证保持此锁



 类似资料:
  • 为什么java可重入锁不会导致死锁?

  • 我第一次做硒测试。在主页上,我调用了一些AJAX,我希望Selenium等待元素加载完成。我不确定它是否有效,但我只是键入selenium,waitForCondition可以选择。 无论我选择什么,它总是返回“false”。我现在连等待条件都不工作吗? 我如何测试它是否有效?在这些代码中我做错了什么? 如果由自己的类实现,则返回“true” isElementPresent(By.xpath(“

  • 主要内容:1 什么是Java可重入锁,2 Java可重入锁的优势,3 Java可重入锁的例子1 什么是Java可重入锁 根据Sun公司的说法,Java锁是可重入的,这意味着,如果从方法中调用方法,则Java线程可以将同一把锁用于不同的同步方法。 2 Java可重入锁的优势 它避免了单线程死锁。 3 Java可重入锁的例子 让我们通过以下示例了解Java可重入锁: 在此类中,m和n是同步方法。m() 方法在内部调用n() 方法。 现在让我们在线程上调用m() 方法。在下面给出的类中,我们使

  • 我在学习Java中的重入锁定。需要一定的澄清这个概念,它实际上是如何工作的。下面的片段我所理解的是:

  • Python有一个名为<code>Condition或<code>notify_all()。然而,在调用<code>wait()acquire()wait()方法然后释放锁并等待通知,然后它将继续重新获取锁,您可以运行一些需要线程安全的代码。我的问题是,当调用<code>wait()方法时,<code>条件</code>对象为什么不在内部自动获取锁: 必须调用其他方法并按住关联的锁。 方法释放锁,

  • 我对Java同步()块的理解是,如果一个线程已经拥有一个对象上的锁,它可以进入一个在同一个对象上同步的不同块(重入同步)。下面,我相信JVM使用引用计数来增加/减少线程获得锁的次数,并且锁只有在计数为零时才会释放。 所以我的问题是,如果你遇到这样的代码: 当调用etc()时,具体会发生什么?它仅仅是减少计数,还是不顾计数释放锁? 在第一种情况下,在我看来,如果发生了锁重新进入,它将产生死锁,因为它