Reputation: 13845
I am working on a simple Semaphore program in which i am initializing a Semaphore with a count of 4 and starting 6 threads. Inside the run method, i am acquiring the Semaphore lock and after completion of each thread, i am releasing the lock.
Here is my code:
import java.util.concurrent.Semaphore;
public class SemaphoreTest {
static Semaphore semaphore = new Semaphore(4, true);
static class MyThread extends Thread{
String name = "";
public MyThread(String name){
this.name = name;
}
public void run(){
System.out.println(name+" going to acquire lock...");
System.out.println("Available Permits = "+semaphore.availablePermits());
try {
semaphore.acquire();
System.out.println(name+" got permit.");
try{
for(int i=1;i<=1;i++){
System.out.println(name+" is performing operation "+i+". Available Semaphore permits are : "+semaphore.availablePermits());
Thread.sleep(1000);
}
}finally{
System.out.println(name+" Releasing lock...");
semaphore.release();
System.out.println("Available permits after releasing "+"name"+" = "+semaphore.availablePermits());
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args){
Thread t1 = new MyThread("A");
t1.start();
Thread t2 = new MyThread("B");
t2.start();
Thread t3 = new MyThread("C");
t3.start();
Thread t4 = new MyThread("D");
t4.start();
Thread t5 = new MyThread("E");
t5.start();
Thread t6 = new MyThread("F");
t6.start();
}
}
And here is the result:
A going to acquire lock...
Available Permits = 4
C going to acquire lock...
A got permit.
A is performing operation 1. Available Semaphore permits are : 3
B going to acquire lock...
Available Permits = 3
B got permit.
F going to acquire lock...
E going to acquire lock...
Available Permits = 2
Available Permits = 3
D going to acquire lock...
Available Permits = 0
C got permit.
C is performing operation 1. Available Semaphore permits are : 0
E got permit.
E is performing operation 1. Available Semaphore permits are : 0
Available Permits = 2
B is performing operation 1. Available Semaphore permits are : 2
A Releasing lock...
E Releasing lock...
Available permits after releasing name = 2
D got permit.
D is performing operation 1. Available Semaphore permits are : 1
B Releasing lock...
C Releasing lock...
Available permits after releasing name = 1
F got permit.
F is performing operation 1. Available Semaphore permits are : 2
Available permits after releasing name = 2
Available permits after releasing name = 2
D Releasing lock...
F Releasing lock...
Available permits after releasing name = 3
Available permits after releasing name = 4
Now as of the java documentation:
java.util.concurrent.Semaphore.Semaphore(int permits, boolean fair)
Creates a Semaphore with the given number of permits and the given fairness setting.
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.
fair
true if this semaphore will guarantee first-in first-out granting of permits under contention, else false
The constructor Semaphore(int permits, boolean fair), guarantees first-in-first-out. But as of the output of this program, it is not the same. The locks are aquired as follows:
A -> B -> C -> E
And the locks are released as follows:
A -> E -> B -> C
Please suggest is it as expected? Or there is something i am missing?
Upvotes: 3
Views: 1020
Reputation: 14269
There is a misunderstanding about thread timing here: you assume that as soon as the thread outputs the message it will acquire the lock, but in fact there is no reason why the thread should not be put on hold in between.
C: System.out.println(...);
C: thread gets put on hold
A: System.out.println(...);
A: aquires lock
B: System.out.println(...);
B: aquires lock
C: resumes
C: aquires lock
Upvotes: 0
Reputation: 328619
The order in which the permits are released is simply a consequence of the time spent in the run
method and has nothing to do with fairness.
FIFO here means that if two threads call semaphore.acquire()
and no permit is available, the thread that called it first will be the first to receive a permit when one becomes available.
In your example, A, B, C, E get permits because they call acquire
first - and D and F have to wait for a permit to become available. Then it seems that D calls acquire
before F and therefore gets the first available permit.
Upvotes: 3