java - 在可重入锁中等待条件

标签 java synchronization

以下代码取自 JavaDoc of Condition :

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();
    }
  } 
}

想象 2 个线程,ConsumerProducer,一个使用 take,一个 put 在单个实例上有界缓冲区

假设 Consumer 首先运行,运行 take(),他在其中锁定 lock,现在在 notEmpty.await 上循环();

现在 Producer 怎么可能进入 put() 方法而不是锁定 已经持有的 lock消费者

我在这里缺少什么? lock 在线程等待其条件之一时是否“临时释放”?那么锁的reentrancy到底是什么意思?

最佳答案

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

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

来自 Condition.await()

The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the signal() method for this Condition and the current thread happens to be chosen as the thread to be awakened; or
  • Some other thread invokes the signalAll() method for this Condition; or
  • Some other thread interrupts the current thread, and interruption of thread suspension is supported; or
  • A "spurious wakeup" occurs.

In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock

关于java - 在可重入锁中等待条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12578687/

相关文章:

java - 验证java中的字符串

Java 相当于.Net 的AutoResetEvent?

java - Java 中方法一致性问题

java - 在更新共享变量时消除过度同步并改进错误处理

java - 修改 CopyOnWriteArraySet 时出现 UnsupportedOperationException

java - 在 Java 中追加到文本文件的特定部分

java - 反序列化集合时不安全的泛型转换

java - 当按下其他键时,该键被取消注册

java - 无法使用 FileReader 和 BufferedReader 在 Java 中读取文本文件

c - 同步两个线程