Reputation: 435
I am currently doing the design of a counting semaphore in C++ trying to conform to the same level of standard as Java except for the InterupptedExceptions since C++ std:: threads do not support interruption. I was reading the class documentation in Java and came across two questions that really baffle me at this moment.
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Semaphore.html
Question 1:
regarding releasing of permits i see that a statement "There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire()" In the implementation of acquire. If there is no ownership concept of acquring a permit and releasing it by same thread in design then what happens in below case.
some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?
Question 2:
What happens if a thread acquires a semaphore count and throws an exception where the release is simply missed out perhaps because exception propagates outside of the class of that thread function. Does this lead to permit leak in such case ?
Upvotes: 1
Views: 442
Reputation: 538
My two cents:
some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?
Semaphore is not a lock, so there is no need to acquire a permit before releasing it. You can even initialize a semaphore with negative initial value. So answer to your first question is that if any thread releases permit(s), it will simply increment the permit count by the number of permits released.
Does this lead to permit leak in such case ?
On similar lines, if a thread decrements permit(s) by acquiring and fails due to any reason without releasing it, the count will stay the same. I won't call it a leak, since it is possible to have a scenario where end user simply wishes to consume the permits, without ever releasing one.
Upvotes: 0
Reputation: 28269
some rogue thread simply tries to run release and it has never acquired any at all. What will get released then? does it silently return and do nothing?
It's better call it increment
instead of release
or return
. You can even create a Semaphore
with a negative permission:
Semaphore semaphore = new Semaphore(-1);
In this situation, if threadA try to aquire()
, it will get blocked until other threads increment the permission by release()
twice.
Does this lead to permit leak in such case ?
That's why it is suggested to use Semaphore
with try catch finally
block when the resource is limited:
semaphore.aquire();
try {
} catch () {
} finally {
semaphore.release();
}
Upvotes: 2