Java examples for Thread:Producer Consumer
Producer and Consumer threads correctly manipulating a circular buffer.
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.security.SecureRandom; class CircularBuffer implements Buffer { private final int[] buffer = {-1, -1, -1}; // shared buffer private int occupiedCells = 0; // count number of buffers used private int writeIndex = 0; // index of next element to write to private int readIndex = 0; // index of next element to read /*w ww.java 2 s. co m*/ public synchronized void blockingPut(int value) throws InterruptedException { while (occupiedCells == buffer.length) { System.out.printf("Buffer is full. Producer waits.%n"); wait(); // wait until a buffer cell is free } buffer[writeIndex] = value; // set new buffer value writeIndex = (writeIndex + 1) % buffer.length; ++occupiedCells; // one more buffer cell is full displayState("Producer writes " + value); notifyAll(); // notify threads waiting to read from buffer } public synchronized int blockingGet() throws InterruptedException { while (occupiedCells == 0) { System.out.printf("Buffer is empty. Consumer waits.%n"); wait(); // wait until a buffer cell is filled } int readValue = buffer[readIndex]; // read value from buffer // update circular read index readIndex = (readIndex + 1) % buffer.length; --occupiedCells; // one fewer buffer cells are occupied displayState("Consumer reads " + readValue); notifyAll(); // notify threads waiting to write to buffer return readValue; } public synchronized void displayState(String operation) { System.out.printf("%s%s%d)%n%s", operation, " (buffer cells occupied: ", occupiedCells, "buffer cells: "); for (int value : buffer) System.out.printf(" %2d ", value); // output values in buffer System.out.printf("%n "); for (int i = 0; i < buffer.length; i++) System.out.print("---- "); System.out.printf("%n "); for (int i = 0; i < buffer.length; i++) { if (i == writeIndex && i == readIndex) System.out.print(" WR"); // both write and read index else if (i == writeIndex) System.out.print(" W "); // just write index else if (i == readIndex) System.out.print(" R "); // just read index else System.out.print(" "); // neither index } System.out.printf("%n%n"); } } interface Buffer { public void blockingPut(int value) throws InterruptedException; public int blockingGet() throws InterruptedException; } class Producer implements Runnable { private static final SecureRandom generator = new SecureRandom(); private final Buffer sharedLocation; // reference to shared object public Producer(Buffer sharedLocation) { this.sharedLocation = sharedLocation; } // store values from 1 to 10 in sharedLocation public void run() { int sum = 0; for (int count = 1; count <= 10; count++) { try // sleep 0 to 3 seconds, then place value in Buffer { Thread.sleep(generator.nextInt(3000)); // random sleep sharedLocation.blockingPut(count); // set value in buffer sum += count; // increment sum of values } catch (InterruptedException exception) { Thread.currentThread().interrupt(); } } System.out.printf( "Producer done producing%nTerminating Producer%n"); } } class Consumer implements Runnable { private static final SecureRandom generator = new SecureRandom(); private final Buffer sharedLocation; // reference to shared object // constructor public Consumer(Buffer sharedLocation) { this.sharedLocation = sharedLocation; } // read sharedLocation's value 10 times and sum the values public void run() { int sum = 0; for (int count = 1; count <= 10; count++) { // sleep 0 to 3 seconds, read value from buffer and add to sum try { Thread.sleep(generator.nextInt(3000)); sum += sharedLocation.blockingGet(); } catch (InterruptedException exception) { Thread.currentThread().interrupt(); } } System.out.printf("%n%s %d%n%s%n", "Consumer read values totaling", sum, "Terminating Consumer"); } } public class Main { public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); CircularBuffer sharedLocation = new CircularBuffer(); sharedLocation.displayState("Initial State"); executorService.execute(new Producer(sharedLocation)); executorService.execute(new Consumer(sharedLocation)); executorService.shutdown(); executorService.awaitTermination(1, TimeUnit.MINUTES); } }