在try-catch块中包装信号量动作的正确方法是什么?如果获取行动在获得一些但不是全部的许可证后被中断,会发生什么?你怎么知道再发布多少?是否应该发布"最后"阻止,但是,如果行动被中断,你可能还没有发放许可证吗?
try {
lock.acquire(permits);
//Do some things that require synchronization
//Make sure to release all of the permits again!
lock.release(permits);
} catch (InterruptedException e) {
log.error("Interrupted!");
}
答案 0 :(得分:4)
Semaphore.acquire(int)
方法是全部或全部操作,要么获得所有请求的许可,要么阻止。您可以使用双重尝试代码,或让(可能的)中断异常来获取冒充您的调用堆栈。
try {
lock.acquire(permits);
try {
// do some stuff here
} finally {
lock.release(permits);
}
} catch(final InterruptedException ie) {
// handle acquire failure here
}
lock.acquire(permits);
try {
// do some stuff here
} finally {
lock.release(permits);
}
在切线上,请记住,信号量必须通过严格的编程约定保持平衡,因此您应该始终释放许多许可证。
答案 1 :(得分:0)
以add
中的BoundedHashSet
方法为例,
public boolean add(T o) throws InterruptedException {
sem.acquire();
boolean wasAdded = false;
try {
wasAdded = set.add(o);
return wasAdded;
} finally {
if (!wasAdded)
sem.release();
}
}
如果sem.acquire();
抛出InterruptedException,则try块和finally块将被跳过。
否则,我们将成功获取信号量,请尝试块并最终将完全执行块。也就是说,我们将发放与获得的相同数量的许可证。
答案 2 :(得分:0)
要添加@Perception 的答案,您可以选择分离嵌套的双重 try-catch 并在获取块上添加重试,这适合我的用例。
df1 <- structure(list(trial = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L), fixation = c(0L, 0L, 1L, 1L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-14L))