【问题标题】:java ArrayBlockingQueue put and take at the same time will cause deadlock?java ArrayBlockingQueue put和take同时会导致死锁吗?
【发布时间】:2014-09-21 22:23:58
【问题描述】:

ArrayBlockingQueue 的 take 和 put 函数如下所示:

`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()。然后调用线程将通过 notEmpty.await() 等待,同时线程持有锁监视器。如果我从另一个假设将新元素添加到队列中的线程调用 put(),则 put() 函数将在 lock.lock() 行等待,直到 take() 调用 unlock()。我对么?如果我是正确的,就会出现僵局。

【问题讨论】:

  • 来自docs"Attempts to put an element into a full queue will result in the operation blocking; attempts to take an element from an empty queue will similarly block."

标签: java concurrency


【解决方案1】:

不,Condition#await() 状态的 javadoc

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

所以Lock对象被释放,可以被另一个线程获取。

【讨论】:

  • 我说的是lock.lock()的锁;和 lock.unlock(),因为两个函数使用同一个锁对象。当 take() 在 lock.lock() 之后等待并在调用 lock.unlock() 之前等待,函数 put() 将在 lock.lock() 行被阻塞。
  • @tommi notEmpty 引用从该Lock 对象创建的Condition 对象。当您在其上调用await 时,它会释放该锁。
猜你喜欢
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多