Two threads manipulating a blocking buffer that properly implements the producer/consumer relationship. - Java Thread

Java examples for Thread:Producer Consumer

Description

Two threads manipulating a blocking buffer that properly implements the producer/consumer relationship.

Demo Code

import java.security.SecureRandom;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class BlockingBuffer implements Buffer {
  private final ArrayBlockingQueue<Integer> buffer; // shared buffer

  public BlockingBuffer() {
    buffer = new ArrayBlockingQueue<Integer>(1);
  }/*w w  w  .j a v  a 2s .  c  om*/
  public void blockingPut(int value) throws InterruptedException {
    buffer.put(value); // place value in buffer
    System.out.printf("%s%2d\t%s%d%n", "Producer writes ", value,
        "Buffer cells occupied: ", buffer.size());
  }
  public int blockingGet() throws InterruptedException {
    int readValue = buffer.take(); // remove value from buffer
    System.out.printf("%s %2d\t%s%d%n", "Consumer reads ", readValue,
        "Buffer cells occupied: ", buffer.size());

    return readValue;
  }
}

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

  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");
  }
}

interface Buffer {
  public void blockingPut(int value) throws InterruptedException;
  public int blockingGet() throws InterruptedException;
}
public class Main {
  public static void main(String[] args) throws InterruptedException {
     ExecutorService executorService = Executors.newCachedThreadPool();

    Buffer sharedLocation = new BlockingBuffer();

    executorService.execute(new Producer(sharedLocation));
    executorService.execute(new Consumer(sharedLocation));

    executorService.shutdown();
    executorService.awaitTermination(1, TimeUnit.MINUTES);
  }
}

Result


Related Tutorials