Please tell what is difference between a Semaphore
initialized with 1 and Vs. intialized zero, as below:
public static Semaphore semOne = new Semaphore(1);
and
public static Semaphore semZero = new Semaphore(0);
Please tell what is difference between a Semaphore
initialized with 1 and Vs. intialized zero, as below:
public static Semaphore semOne = new Semaphore(1);
and
public static Semaphore semZero = new Semaphore(0);
The argument to the Semaphore instance is the number of "permits" that are available. It can be any integer, not just 0 or 1.
For semZero
all acquire()
calls will block and tryAcquire()
calls will return false, until you do a release()
For semOne
the first acquire()
calls will succeed and the rest will block until the first one releases.
The class is well documented here.
Parameters: permits - the initial number of permits available. This value may be negative, in which case releases must occur before any acquires will be granted.
the constructor parameter permits
(initial semaphore counter) is the number of calls to Semaphore.aquire()
that can be made before the counter (permits) is zero, and the acquire()
blocks.
1 is a normal value, to ensure that only one thread passes the acquire.
semaphore.acquire();
try {
// Critical region
...
} finally {
semaphore.release();
}
For a usage of 0 see here.
Semaphore is a low-level mechanism for concurrency: a counter when reaching zero blocking thread execution. It stems from Dijkstra where the binary semaphore (0, 1) is a metaphore for a railway semaphore saying pass (halt when 0, pass --permits) and at the end of the protected track does a release (++permits).
When I first read the documentation of the Semaphore I also misinterpreted the explanation. The main point I missed was the part of '...INITIAL number of permits...'. Somehow I though this would be the number of permits which would be available as a MAXIMUM, but that is NOT the case. In the end the semaphore just counts up from any number but only starts the enable waiting threads (which use the acquire) when the semaphore permits are above 1.
A simple piece of (non threading) code shows this too:
@Test
public void testNegativeSemaphore()
{
Semaphore semaphore = new Semaphore(-2);
assertEquals(-2, semaphore.availablePermits());
semaphore.release();
assertEquals(-1, semaphore.availablePermits());
semaphore.release();
assertEquals(0, semaphore.availablePermits());
semaphore.release();
assertEquals(1, semaphore.availablePermits());
}
As the code shows, the available permits increase upon each release, only to allow other threads to acquire a permit once the value reaches 1 or above.
NOTE that from there on the availablePermits cannot become negative by using the aqcuire because if there are 0 permits the whole point of the semaphore is to wait for a permit to become available again!