I am new to the consumer producer problem and the Semaphore. The following code is getting Deadlocked in the condition that Producer thread gets stuck when it is acquiring the permit again just after adding in the queue..
Only this is the case when program is deadlocked.
public class UsingSemaphore {
volatile static boolean check = true;
public static void main(String args[]) throws InterruptedException {
Semaphore semCon = new Semaphore(0);
Semaphore semProd = new Semaphore(1);
Queue<Integer> q = new LinkedList<>();
// Producer lambda
Runnable producer = () -> {
while (check) {
try {
semProd.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Random rand = new Random();
q.add(rand.nextInt(10));
}finally {
semCon.release();
}
}
};
//Consumer lambda
Runnable consumer = () -> {
while (check) {
try {
semCon.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
System.out.println("Consumer item " + q.remove());
}finally {
semProd.release();
}
}
};
ThreadGroup pg = new ThreadGroup("PG");
ThreadGroup cg = new ThreadGroup("CG");
Thread p1 = new Thread(pg, producer, "p1");
Thread c1 = new Thread(cg, consumer, "c1");
p1.start();
c1.start();
Thread.sleep(10);
check = false;
}
}
The consumer thread does not run in the test case where producer goes to acquire permit... please somebody help
Your problem is I think the lack of synchronization around the check
flag that allows your loop to start or end.
It is possible for instance that the producer starts the loop and waits for semProd.acquire()
(on its second iteration) but the consumer never actually started because the check
flag was evaluated to false.
When the loops end, both the consumer and the producer must end at the right time or a deadlock can occur when you consider the sequence of events:
C1: semProd.release()
P1: semProd.acquire() -> OK
P1: q.add()
P1: semCon.release()
P1: while(check) -> IN
P1: semProd.acquire() -> wait
MAIN: check <- false
C1: while(check) -> OUT
C1: stops
P1: deadlocked
Same applies the other way around if C1 is trying to acquire semCon
.