尝试捕获信号量的正确方法

时间:2013-02-28 15:23:07

标签: java try-catch semaphore

在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!");
}

3 个答案:

答案 0 :(得分:4)

Semaphore.acquire(int)方法是全部或全部操作,要么获得所有请求的许可,要么阻止。您可以使用双重尝试代码,或让(可能的)中断异常来获取冒充您的调用堆栈。

Double try block:

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))