I'm learning about Mutex and Semaphore in Java. So I thought of getting my hands dirty.
I understand that mutex is semaphore with single permit from this link and mutex has the concept of ownership from this link.
To demonstrate ownership I wrote below program and found below output. When I do release more than acquires, it actually increases the number of permits.
Below is the program.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
public class MutexOwnerShipDemo {
public static void main(String[] args) {
Semaphore mutex = new Semaphore(1);
final ExecutorService es = Executors.newSingleThreadExecutor();
try {
// acquire mutex lock permit in main thread
mutex.acquire();
// release the lock in different thread
Future mutexWait = es.submit(() -> mutex.release());
mutexWait.get();
System.out.println("mutexWait.isDone() " + mutexWait.isDone() );
System.out.println("successfully released permits for mutex \n " +
"available permits are " + mutex.availablePermits());
// release the lock in main thread
mutex.release();
System.out.println( "available permits are " + mutex.availablePermits());
// release lock in main thread once again
mutex.release();
System.out.println( "available permits are " + mutex.availablePermits());
} catch (Exception e) {
}
Runtime.getRuntime().addShutdownHook(new Thread(() -> es.shutdownNow()));
System.out.println(es.isShutdown());
}
}
The output is -
mutexWait.isDone() true
successfully released permits for mutex
available permits are 1
available permits are 2
available permits are 3
false
Is this behavior expected. If so, how this works
My java installation details -
$ java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
There is no requirement that a thread that releases a permit must have acquired that permit by calling acquire().
Exits the semaphore a specified number of times and returns the previous count.
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.
Yes, a negative value means you have processes waiting for the semaphore to be released. A positive value means you can call acquire that many times before the semaphore blocks.
A couple of things:
Semaphore
, which can have any number of permits, so yes it is expected. See the Javadoc: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.
ReentrantLock
, or a simple Object
used with a synchronized
block.Yes, it's the expected behaviour cited in the documentation:
[...] Releases a permit, increasing the number of available permits by one. [...] There is no requirement that a thread that releases a permit must have acquired that permit by calling
acquire()
.
You can release as many permits as you want to:
Semaphore semaphore = new Semaphore(0);
semaphore.release(10); // it's fine
System.out.println(semaphore.availablePermits()); // 10
You can't obtain a random number of permits (precisely, a number that exceeds the current number of permits available), though:
Semaphore semaphore = new Semaphore(0);
semaphore.acquire(10); // you are blocked here
Semaphore semaphore = new Semaphore(0);
System.out.println(semaphore.tryAcquire(10)); // false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With