正确实现信号量的锁定?

时间:2014-06-06 17:32:12

标签: java concurrency semaphore

我不确定以下实现是否正确。我的理由是,如果当前线程在等待发出信号时被中断,则会调用finally块,但由于它没有持有锁,因此将抛出IllegalMonitorStateException。在这种情况下,我是否正确实施了try-finally块,或者应该实现一个块?

  public void acquire() throws InterruptedException {
    try {
      lock.lockInterruptibly();
      while (permits == 0) {
        condition.await();
      }
      permits--;
    }
    finally {
      lock.unlock();
    }
  }

3 个答案:

答案 0 :(得分:1)

不确定我是否正确理解问题,但您应该尝试 - 在分配资源后最终只

  public void acquire() throws InterruptedException {
    lock.lockInterruptibly(); // allocate resource before try
    try {
      while (permits == 0) {
        condition.await();
      }
      permits--;
    }
    finally {
      lock.unlock();
    }
  }

我不知道为什么所有的学校,例如Sun's official page on finally,建议在finally子句中分配try(以便你需要if(allocated) {release})。这是愚蠢的IMO。为什么每个人都建议在try中分配?

答案 1 :(得分:1)

一个好问题。我自己对结果感到惊讶。

如果发生InterruptedException,则条件将停止awaiting,然后执行finally。显然不会拥有锁并传播IllegalMonitorStateException

答案 2 :(得分:0)

这个解决方案怎么样?

  public void acquire() throws InterruptedException {
    lock.lockInterruptibly();
    while (permits == 0) {
      condition.await();
    }
    try {
      permits--;
    }
    finally {
      lock.unlock();
    }
  }

await返回时,当前线程将具有锁定。如果它在等待其他线程发出信号时被中断(即它没有锁定),acquire会将InterruptedException反馈给调用者。