Решение проблемы производителя-потребителя с помощью 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
...
Здесь производитель начинает создавать объекты и помещать их в очередь. Как только очередь заполнится, производитель будет ждать, пока потребитель ее не потребляет, и он снова начнет производство. Аналогичное поведение демонстрирует потребитель, где потребитель ждет, пока в очереди не появится единственный элемент. Он возобновит работу потребителя, как только в очереди появится элемент.
Читайте также:
- Интерфейсы Comparable и Comparator в Java
- Разница между fail-fast и fail-safe итератором в Java
- Коллекции, предоставляемые интерфейсом Map в Java
Комментарии
Отправить комментарий