Reputation: 647
When I usesemaphor with 1 argument. And then Release it twice, it increases available permits to 2 but ideally i have already mentioned that i want 1 lock. Now since i have 2 available permits two thread can acquire the lock which defeats the purpose of argument.
Semaphor lock = new Semaphor(1);
lock.release();
lock.release();
lock.acquire(); // thread1
lock.acquire(); //thread2
Why does it behave like that?
Upvotes: 1
Views: 43
Reputation: 719679
Now since i have 2 available permits two thread can acquire the lock which defeats the purpose of argument.
It doesn't defeat the purpose of a Semaphore
. The purpose of Semaphore
is to implement the counting semaphore abstraction as described here.
Why
Semaphore
doesn't honor the argument provided?
It does honor it. But the argument isn't a bound on the number of permits. Rather it represents the number of permits that initially may be acquire without blocking.
Why does it behave like that?
Because (in the opinion of the Java designers) that is the way that a counting semaphore should behave.
The standard Semaphore
class does not have a way to restrict the number of permits. If you want a lock (or a binary semaphore) you should use a Lock
class ...
But in multi threading app it is possible that release and acquire goes out of sync and it ends up calling release twice.
Yes. That would be a bug in the application.
Now ... if you wanted to detect that, you could extend the Semaphore
class and override the acquire
and release
methods to check that the number of permits stays between prescribed bounds. (You could throw an unchecked exception if the check failed. Or you could silently ignore the request ... though that sounds like a bad idea.)
Upvotes: 0
Reputation: 28289
Why does it behave like that?
The doc mentions it:
When used in this way, the binary semaphore has the property (unlike many Lock implementations), that the "lock" can be released by a thread other than the owner (as semaphores have no notion of ownership). This can be useful in some specialized contexts, such as deadlock recovery.
You can use a wrapper class to track the initial permit. But usually, it is not supposed to call release
until the thread aquire
the lock, so it should not become a problem.
Upvotes: 1
Reputation: 9
release()
From Oracle doc : Releases a permit, increasing the number of available permits by one. If any threads are trying to acquire a permit, then one is selected and given the permit that was just released. That thread is (re)enabled for thread scheduling purposes.
There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire(). Correct usage of a semaphore is established by programming convention in the application.
Upvotes: 0