我目前正在用C ++进行计数信号量的设计,试图符合与Java相同的标准级别,但InterupptedExceptions除外,因为C ++ std ::线程不支持中断。我当时正在阅读Java中的类文档,遇到了两个问题,这些问题现在真的让我感到困惑。
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Semaphore.html
问题1:
关于释放许可证的问题,我看到在获取的实现中,有一条语句“不要求释放许可证的线程必须已经通过调用invoke()获得了该许可证。” 如果在设计中没有所有权许可的概念并通过同一线程释放,那么在以下情况下会发生什么。一些流氓线程只是尝试运行release,而根本没有获取任何流氓线程。那会释放什么呢? 它会默默地返回而什么都不做吗?
问题2:
如果线程获取信号量计数并抛出异常而导致释放被遗漏,可能是因为异常传播到该线程函数的类之外,该怎么办?在这种情况下是否会导致泄漏?
答案 0 :(得分:2)
一些流氓线程只是尝试运行release,而且从未 完全没有获得。那会释放什么呢?默默地做 返回并什么都不做?
最好将其称为increment
,而不是release
或return
。您甚至可以创建具有拒绝权限的Semaphore
:
Semaphore semaphore = new Semaphore(-1);
在这种情况下,如果线程A尝试aquire()
,它将被阻塞,直到其他线程将release()
的权限增加两次为止。
在这种情况下是否会导致泄漏?
这就是为什么在资源有限的情况下建议在Semaphore
块中使用try catch finally
的原因:
semaphore.aquire();
try {
} catch () {
} finally {
semaphore.release();
}
答案 1 :(得分:0)
我的两分钱
一些流氓线程只是尝试运行release,而根本没有获取任何流氓线程。那会释放什么呢?它会默默地返回而什么也不做吗?
信号量不是锁,因此在释放它之前不需要获得许可。您甚至可以使用负初始值来初始化信号量。因此,对第一个问题的回答是,如果有任何线程释放许可证,则只会将许可证计数增加已释放的许可证数量。
在这种情况下是否会导致泄漏?
在相似的行上,如果线程递减允许通过获取而由于某种原因而失败而未释放它,则计数将保持不变。我不会称其为泄漏,因为有可能出现这样一种情况,即最终用户只是希望消耗许可证,而不必释放许可证。