13

从 Java java.util.concurrent.Semaphore 文档中,我不太清楚如果 semaphore.acquire() 阻塞线程并随后被 InterruptedException 中断会发生什么。信号量值是否降低了,是否需要释放信号量?

目前我正在使用这样的代码:

try {
  // use semaphore to limit number of parallel threads
  semaphore.acquire();
  doMyWork();
}
finally {
  semaphore.release();
}

或者我应该在 acquire() 期间发生 InterruptedException 时不调用 release() ?

4

3 回答 3

13

在 acquire() 期间发生 InterruptedException 时调用 release() ?

你不应该。如果 .acquire() 被中断,则不会获取信号量,因此可能不应该释放它。

你的代码应该是

// use semaphore to limit number of parallel threads
semaphore.acquire();
try {
  doMyWork();
}
finally {
  semaphore.release();
}
于 2012-08-24T07:48:13.037 回答
8

nos 接受的答案是部分正确的,除了 semaphore.acquire() 也会抛出 InterruptedException。因此,为了 100% 正确,代码如下所示:

try {
    semaphore.acquire();
    try {
        doMyWork();
    } catch (InterruptedException e) { 
        // do something, if you wish
    } finally {
        semaphore.release();
    }
} catch (InterruptedException e) {
    // do something, if you wish
}
于 2014-02-21T05:23:03.400 回答
0

如果线程在acquire方法调用之前被中断,或者在等待获取permit时,会抛出InterruptedException,并且不会持有permit,所以不需要释放。只有当您确定已获得许可时(在调用获取方法调用之后),您才需要释放许可。因此,您最好在尝试块开始之前获取,例如:

sem.acquire();
try{
   doMyWork();
}finally{
   sem.release();
}
于 2012-08-24T07:55:00.557 回答