Решение проблемы производителя-потребителя с помощью BlockingQueue в Java

BlockingQueue: когда поток пытается исключить из пустой очереди, блокируется до тех пор, пока какой-либо другой поток не вставит элемент в очередь. Кроме того, когда поток пытается поставить элемент в полную очередь, он блокируется до тех пор, пока какой-либо другой поток не освободит место в очереди, либо исключив один или несколько элементов из очереди, либо полностью очистив очередь.

Проблема производителя и потребителя

Производитель и Потребитель (Producer & Consumer) - это два отдельных потока, которые используют одну и ту же ограниченную очередь. Роль производителя производить элементы и помещать их в очередь. Производитель останавливает производство, если очередь заполнена, и возобновляет производство, когда размер очереди не заполнен. Потребитель потребляет элемент из очереди. Потребители прекращают потребление, если размер очереди равен 0 (пусто), и возобновляют потребление, когда в очереди есть элемент.

Подойти к решению проблемы можно разными способами.

  • Использование wait() и notifyAll()
  • Использование BlockingQueue
  • Использование семафоров

Ниже представлен вариант решения с использованием BlockingQueue:

public class ProducerConsumerBlockingQueue {

  static int MAX_SIZE = 5;
  static BlockingQueue queue = 
         new LinkedBlockingQueue(MAX_SIZE);

  public static void main(String[] args) {

    Producer producer = new Producer();
    Consumer consumer = new Consumer();
    producer.start();
    consumer.start();
  }

  static class Producer extends Thread {
    Random random = new Random();

    public void run() {
      while (true) {
        int element = random.nextInt(MAX_SIZE);
        try {
          queue.put(element);
          System.out.println("Producer " + String.valueOf(element));
        } catch (InterruptedException e) {
        }
      }
    }
  }

  static class Consumer extends Thread {
    public void run() {
      while (true) {
        try {
          System.out.println("Consumed " + queue.take());
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
}

Вывод:

Producer 2
Producer 3
Consumed 2
Consumed 3
Producer 0
Producer 4
Consumed 0
...

Здесь производитель начинает создавать объекты и помещать их в очередь. Как только очередь заполнится, производитель будет ждать, пока потребитель ее не потребляет, и он снова начнет производство. Аналогичное поведение демонстрирует потребитель, где потребитель ждет, пока в очереди не появится единственный элемент. Он возобновит работу потребителя, как только в очереди появится элемент.


Читайте также:


Комментарии

Популярные сообщения из этого блога

Методы класса Object в Java

Как получить текущий timestamp в Java

Основные опции JVM для повышения производительности и отладки