Java producer consumer code example with wait and notifyAll
This simple Java multi-threaded code can be used for practicing your ability to debug concurrency issues. You will also learn the producer consumer inter thread communication in Java.
Step 1: The ProducerConsumerTest class that is runnable as a default Java main thread. Responsible for producing 2 worker threads ProducerThread and ConsumerThread.
public class ProducerConsumerTest {
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
//spawn a new producer thread and start
Thread producer = new Thread(new ProducerThread(pc));
producer.start();
Thread.sleep(1000); //main thread sleeps for 1 second
//spawn a new consumer thread and start
Thread consumer = new Thread(new ConsumerThread(pc));
consumer.start();
}
}
Step 2: The ProducerThread and ConsumerThread classes that run as worker threads and share The ProducerConsumer class that has the logic to produce and consume.
public class ProducerThread implements Runnable {
private ProducerConsumer pc;
public ProducerThread(ProducerConsumer pc) {
this.pc = pc;
}
@Override
public void run() {
pc.produce();
}
}
public class ConsumerThread implements Runnable {
private ProducerConsumer pc;
public ConsumerThread(ProducerConsumer pc) {
this.pc = pc;
}
@Override
public void run() {
pc.consume();
}
}
Step 3: Finally, the ProducerConsumer class that gets accessed by the worker threads to get th job done. The inter thread communication is done via the methods wait( ) and notifyAll( ). Both the produce( ) and consume( ) methods are synchronized as only one thread can acquire the lock to either to produce or to consume. The notify/notifyAll methods relinquishes the lock for any waiting (i.e. blocked) threads to acquire.
import java.util.concurrent.ArrayBlockingQueue;
//only one thread can access either produce or consume methods as both are synchronized
public class ProducerConsumer {
private int count = 0;
private ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(100);
} catch (InterruptedException ie) {}
if (queue.isEmpty()) {
count++;
try {
Thread.sleep(4000); // takes 4 secs to produce
} catch (InterruptedException e) {}
queue.add(count);
System.out.println(Thread.currentThread().getName() + " produced: " + count);
notifyAll();
}
}//end while
}
public synchronized void consume() {
while (true) {
try {
wait(100);
} catch (InterruptedException ie) {}
if (!queue.isEmpty()) {
Integer consumed = queue.remove(); // consumed
System.out.println(Thread.currentThread().getName() + " consumed: " + consumed);
notifyAll();
}
}//end while
}
}
Step 4: The above program keeps running until you kill it. The output will be something like shown below every 4 seconds.
Thread-0 produced: 1 Thread-1 consumed: 1 Thread-0 produced: 2 Thread-1 consumed: 2 Thread-0 produced: 3 Thread-1 consumed: 3 Thread-0 produced: 4 Thread-1 consumed: 4 Thread-0 produced: 5 Thread-1 consumed: 5 Thread-0 produced: 6 Thread-1 consumed: 6 Thread-0 produced: 7 Thread-1 consumed: 7 //...............
In the next post will demonstrate how to debug multi-threaded applications using this code example. \
Labels: Multi-threading


0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home