Java信号量实现和设计相关问题

时间:2018-08-31 03:27:46

标签: java multithreading concurrency semaphore

我目前正在用C ++进行计数信号量的设计,试图符合与Java相同的标准级别,但InterupptedExceptions除外,因为C ++ std ::线程不支持中断。我当时正在阅读Java中的类文档,遇到了两个问题,这些问题现在真的让我感到困惑。

https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Semaphore.html

问题1:

关于释放许可证的问题,我看到在获取的实现中,有一条语句“不要求释放许可证的线程必须已经通过调用invoke()获得了该许可证。” 如果在设计中没有所有权许可的概念并通过同一线程释放,那么在以下情况下会发生什么。

一些流氓线程只是尝试运行release,而根本没有获取任何流氓线程。那会释放什么呢? 它会默默地返回而什么都不做吗?

问题2:

如果线程获取信号量计数并抛出异常而导致释放被遗漏,可能是因为异常传播到该线程函数的类之外,该怎么办?在这种情况下是否会导致泄漏?

2 个答案:

答案 0 :(得分:2)

  

一些流氓线程只是尝试运行release,而且从未   完全没有获得。那会释放什么呢?默默地做   返回并什么都不做?

最好将其称为increment,而不是releasereturn。您甚至可以创建具有拒绝权限的Semaphore

Semaphore semaphore = new Semaphore(-1);

在这种情况下,如果线程A尝试aquire(),它将被阻塞,直到其他线程将release()的权限增加两次为止。

  

在这种情况下是否会导致泄漏?

这就是为什么在资源有限的情况下建议在Semaphore块中使用try catch finally的原因:

semaphore.aquire();
try {

} catch () {

} finally {
    semaphore.release();
}

答案 1 :(得分:0)

我的两分钱

  

一些流氓线程只是尝试运行release,而根本没有获取任何流氓线程。那会释放什么呢?它会默默地返回而什么也不做吗?

信号量不是锁,因此在释放它之前不需要获得许可。您甚至可以使用负初始值来初始化信号量。因此,对第一个问题的回答是,如果有任何线程释放许可证,则只会将许可证计数增加已释放的许可证数量。

  

在这种情况下是否会导致泄漏?

在相似的行上,如果线程递减允许通过获取而由于某种原因而失败而未释放它,则计数将保持不变。我不会称其为泄漏,因为有可能出现这样一种情况,即最终用户只是希望消耗许可证,而不必释放许可证。