Java - Producer Class for a Blocking Queue

Introduction

The following code uses blocking queue to solve a producer/consumer problem.

A producer accepts a blocking queue and a producer name in its constructor.

It generates a string and adds it to the blocking queue after waiting for a random number of seconds between 1 and 5.

If the blocking queue is full, it will wait until the space is available in the queue.

Demo

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class BQProducer extends Thread {
  private final BlockingQueue<String> queue;
  private final String name;
  private int nextNumber = 1;
  private final Random random = new Random();

  public BQProducer(BlockingQueue<String> queue, String name) {
    this.queue = queue;
    this.name = name;
  }/*  w ww . j a va 2  s  . co m*/

  @Override
  public void run() {
    while (true) {
      try {
        String str = name + "-" + nextNumber;
        System.out.println(name + " is trying to add: " + str
            + ". Remaining capacity: " + queue.remainingCapacity());
        this.queue.put(str);
        nextNumber++;
        System.out.println(name + " added: " + str);

        // Sleep between 1 and 5 seconds
        int sleepTime = (random.nextInt(5) + 1) * 1000;
        Thread.sleep(sleepTime);
      } catch (InterruptedException e) {
        e.printStackTrace();
        break;
      }
    }
  }
}

class BQConsumer extends Thread {
  private final BlockingQueue<String> queue;
  private final String name;
  private final Random random = new Random();

  public BQConsumer(BlockingQueue<String> queue, String name) {
    this.queue = queue;
    this.name = name;
  }

  @Override
  public void run() {
    while (true) {
      try {
        System.out.println(name + " is trying to take an element. "
            + "Remaining capacity: " + queue.remainingCapacity());

        String str = this.queue.take();
        System.out.println(name + " took: " + str);

        // Sleep between 1 and 5 seconds
        int sleepTime = (random.nextInt(5) + 1) * 1000;
        Thread.sleep(sleepTime);
      } catch (InterruptedException e) {
        e.printStackTrace();
        break;
      }
    }
  }
}

public class Main {
  public static void main(String[] args) {
    int capacity = 5;
    boolean fair = true;
    BlockingQueue<String> queue = new ArrayBlockingQueue<>(capacity, fair);

    // Create one producer and two consumer and let them produce
    // and consume indefinitely
    new BQProducer(queue, "Producer1").start();
    new BQConsumer(queue, "Consumer1").start();
    new BQConsumer(queue, "Consumer2").start();
  }
}

Result

Related Topic