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