首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.util.concurrent.locks.Condition是如何工作的?

java.util.concurrent.locks.Condition是如何工作的?
EN

Stack Overflow用户
提问于 2016-04-05 19:49:49
回答 1查看 8.6K关注 0票数 12

阅读有关java.util.concurrent.locks.Condition接口的Java8文档,将给出以下示例:

代码语言:javascript
复制
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();
     }
   }
 }

所以我的主要问题是:条件是如何工作的?

  1. 它是否在开始等待时释放锁?(例如,notFull.await())?
  2. 不同的线程可以获得相同的锁并移动直到它signal()一个条件,唤醒其他线程吗?
  3. 我认为这个例子会导致死锁,因为如果一个线程正在等待缓冲区不是空的,并且它还没有释放锁,那么另一个线程如何获得锁,清空缓冲区,现在满足条件,如果等待缓冲区的线程没有释放锁,那么如何释放锁?

这些是初学者的问题。请帮帮我。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-05 20:03:52

  1. 是的,这是正确的,只要它等待条件,它就会释放锁。await/signal/signalAll实际上与wait/notify/notifyAll具有相同的行为。
  2. 不,ReentrantLock是独占锁,所以只有一个线程可以获得锁。
  3. 请参见#1。当线程调用signalsignalAll时,它分别释放一个或所有等待对应Condition的线程,以便线程或这些线程有资格再次获得锁。但就目前而言,锁仍然属于调用signalsignalAll的线程,直到它通过调用lock.unlock显式释放锁为止。然后,已经/已经释放的线程将能够再次尝试获取锁,能够获得锁的线程将能够再次检查条件(在本例中,这个条件指的是count == items.lengthcount == 0 ),如果没有问题,它将继续进行,否则它将再次await并释放锁,使其对另一个线程可用。
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36435753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档