How and why can a Semaphore give out more permits than it was initialized with?
Solution 1
Instead of "handing out" permit objects, the implementation just has a counter. When a new permit is "created" the counter is increased, when a permit is "returned" the counter is decreased.
This makes for much better performance than creating actual objects all the time.
The tradeoff is that the Semaphore itself cannot detect certain kinds of programming errors (such as unauthorized permit cash-ins, or semaphore leaks). As the coder, you have to make sure to follow the rules on your own.
Solution 2
I think that it means the times what we may require Semaphore as the times we released "extra" and plus the permits it created with.
Such as:
Semaphore s = new Semaphore(1); // one permit when initialize
s.acquire();
s.release();
s.release(); // "extra" release.
At this moment, this semaphore allows one permit originally and one "extra" permit
Solution 3
Can somebody explain this ? From the above statement, it looks like the "permits" can keep growing.
A semaphore is a counter of permits. acquire is like decrement which waits rather than go below zero. It has no upper limit.
Why is it designed this way ?
Because its simple to do so.
Solution 4
As mentioned in first post "Semaphore is not limited to the number of permits it was created with"
Every call to .release() API will increase the permit count by one. So Semaphores doesn't have a fixed permit size
Vinoth Kumar C M
buildit @ wiprodigital https://about.me/vinothkumar.cm
Updated on June 05, 2022Comments
-
Vinoth Kumar C M almost 2 years
I am reading the book Java Concurrency in Practice. In a section about
java.util.concurrent.Semaphore
, the below lines are present in the book. It is a comment about its implementation of "virtual permit" objectsThe implementation has no actual permit objects, and
Semaphore
does not associate dispensed permits with threads, so a permit acquired in one thread can be released from another thread. You can think ofacquire
as consuming a permit andrelease
as creating one; aSemaphore
is not limited to the number of permits it was created with.Can somebody explain this? I am having trouble understanding this. If we create a pool of fixed size, we create a fixed number of "permits". From the above statement, it looks like the "permits" can keep growing. Why is it designed this way?
-
Scorpion over 12 yearsNo upper limit, wouldn't the upper limit be the number of permits?
-
Vishy over 12 yearsThe upper limit is the number of times release minus the number of times acquire has been called. You can call release any number of times. There is an upper limit of Integer.MAX_VALUE in some implementations.
-
slott about 9 yearsSo how does one go about creating a solid semaphore with a maximum of 1 - regardless of how many times release is called ?
-
Vishy about 9 years@slott for that I would use an AtomicBoolean. You can
set(true)
to release andcompareAndSet(true, false)
to acquire. This is non blocking. -
slott about 9 yearsIs it overkill to extend Semaphore and override release to do a drainPermits() ?
-
Dasmowenator about 8 yearsDoes Java provide a different kind of semaphore which actually enforces the permit limit? I just want release() to be a no-op when all the permits have already been released... In a complex system with a lot of threads, it's not so easy to make sure that each thread always acquires and releases exactly one permit.
-
hansvb about 8 years@Dasmowenator: I suppose you could roll your own on top of AtomicInteger. But that does not sound like a good approach. You should really make sure your locking code is logically correct. If you find the need to make release a no-op, that probably means that someone was releasing more locks than they should have. And that will break things that cannot be fixed by just ignoring some semaphore calls.
-
hansvb about 8 yearsYou could also use the traditional "synchronized" way of locking. Less flexible, but safe (no leaks, takes care of re-entrancy etc).
-
Neeraj Yadav over 6 yearscan you explain the .release() working then? So, if i create a semaphore object with 0 then no thread can acquire permit from it? But if i call .release() on it first and then .acquire() in next line, it will allow a thread to acquire permit?
-
LookIntoEast almost 3 yearsI'm confused by this for long; and looks crazy this is allowed