I am learning locks and conditions in Java and have implemented producer and consumer code.Idea is to have 1 producer and N Consumer . But when i run the code , always 1 consumer thread read
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ProdConsumer {
int MAX_ELEMENTS = 10;
Queue<Integer> q ;
Lock lock = new ReentrantLock(false);
Condition read = lock.newCondition();
Condition write = lock.newCondition();
ProdConsumer(){
q = new LinkedList<>();
}
public static void main(String[] args) throws InterruptedException {
ProdConsumer pq = new ProdConsumer();
new Thread(() -> {
try {
new Producer(pq.q).produce(pq.lock,pq.read,pq.write,pq.MAX_ELEMENTS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
System.out.println("Started " + Thread.currentThread().getName());
new Consumer(pq.q).consume(pq.lock,pq.read,pq.write);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
System.out.println("Started " + Thread.currentThread().getName());
new Consumer(pq.q).consume(pq.lock,pq.read,pq.write);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
class Producer {
Queue q;
Producer(Queue q) {
this.q = q;
}
void produce(Lock lock, Condition read, Condition write, int MAX_ELEMENTS) throws InterruptedException {
lock.lock();
try {
int count = 0;
while (count < 1000) {
while (q.size() == MAX_ELEMENTS) {
write.await();
}
q.add(count);
System.out.println(Thread.currentThread().getName() + "PRODUCED " + count);
count++;
read.signalAll();
}
} finally {
lock.unlock();
}
}
}
class Consumer {
Queue q;
Consumer(Queue q ){
this.q = q;
}
void consume(Lock lock, Condition read, Condition write) throws InterruptedException {
lock.lock();
try {
while (true) {
while (q.size() == 0) {
read.await();
}
System.out.println(Thread.currentThread().getName() + "CONSUMED " + q.poll());
Thread.sleep((long)(Math.random() * 1000));
write.signalAll();
}
} finally {
lock.unlock();
}
}
}
Result:
Started Thread-1
Started Thread-2
Thread-0PRODUCED 0
Thread-0PRODUCED 1
Thread-0PRODUCED 2
Thread-0PRODUCED 3
Thread-0PRODUCED 4
Thread-0PRODUCED 5
Thread-0PRODUCED 6
Thread-0PRODUCED 7
Thread-0PRODUCED 8
Thread-0PRODUCED 9
Thread-1CONSUMED 0
Thread-1CONSUMED 1
Thread-1CONSUMED 2
Thread-1CONSUMED 3
Thread-1CONSUMED 4
Thread-1CONSUMED 5
Thread-1CONSUMED 6
Thread-1CONSUMED 7
Thread-1CONSUMED 8
Thread-1CONSUMED 9
Here we can see , even tough both thread starts , always Thread one is consuming. My thought process is , when producer signals all , then either of consumer thread should start. What am i doing wrong ?