Шаблон производителя/потребителя шаблонов проектирования Java

1. Что такое модель производитель/потребитель?

Определенный модуль отвечает за формирование данных, которые обрабатываются другим модулем (модуль здесь является обобщенным и может быть классом, функцией, потоком, процессом и т. д.). Модуль, генерирующий данные, называется производителем, модуль, обрабатывающий данные, называется потребителем. Между производителем и потребителем добавляется буферная зона, которую мы условно называем складом.Производитель отвечает за поступление товара на склад, а потребитель отвечает за прием товара со склада.Это составляет производитель-потребитель модель. .

Структурная схема выглядит следующим образом:


Во-вторых, преимущества модели производителя-потребителя:

1. Развязка:

Благодаря наличию буферов между производителями и потребителями отсутствует прямая зависимость, а степень связанности снижается.

2. Поддержка параллелизма:

Поскольку производитель и потребитель являются двумя независимыми параллельными телами, они соединены буфером в качестве моста.Производителю нужно только закинуть данные в буфер, чтобы продолжить производство следующих данных, а потребителю нужно только начать с Просто взять данные в буфере, чтобы они не блокировались из-за скорости обработки друг друга.

3. Поддержка неравномерной занятости:

У буферов есть еще одно преимущество. Преимущество буфера проявляется, если скорость создания данных бывает быстрой и медленной. Когда данные производятся быстро, у потребителя нет времени на их обработку, а необработанные данные могут временно храниться в буфере. После того, как скорость производства производителя замедлится, потребитель будет медленно избавляться от него.


3. Модель «производитель-потребитель» [то есть «производитель-хранилище-потребитель»] правила, которым следует модель:

1. Производители производят только тогда, когда склад не заполнен, и прекращают производство, когда склад заполнен.
2. Потребители могут потреблять только тогда, когда на складе есть товары, и ждать, когда склад опустеет.
3. Когда потребители обнаруживают, что на складе нет товара для потребления, они уведомляют производителя о производстве.
4. Когда производитель производит потребляемый продукт, он должен уведомить об этом ожидающего потребителя.

4. Пример исходного кода:

1. Склад:
package com.hongri.designpattern.producer_consumer;

import java.util.LinkedList;

/**
 * 仓库【即共享数据区域】
 */
public class SyncStack {
    
    
    LinkedList<Integer> list = new LinkedList<>();
    int capacity = 10;
    public volatile int index;

    /**
     * 供生产者调用
     *
     * @param value
     */
    public synchronized void push(String producerName, int value) {
    
    
        while (list.size() >= capacity) {
    
    
            try {
    
    
                System.out.println("仓库已满 ---> 生产者--进入wait状态");
                wait();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }

        //没有满,则继续produce
        System.out.println("生产者--" + producerName + "--生产了:" + value);
        list.add(value);
        //唤醒其他所有处于wait()的线程,包括消费者和生产者
        notifyAll();
    }

    /**
     * 供消费者调用
     *
     * @return
     */
    public synchronized int pop(String consumerName) {
    
    
        int val = 0;
        while (list.size() == 0) {
    
    
            try {
    
    
                System.out.println(" 仓库无货 ---> 消费者--进入wait状态");
                wait();
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        //如果有数据,继续consume
        val = list.removeFirst();
        System.out.println("   消费者------" + consumerName + "--消费了:" + val);
        notifyAll();
        return val;
    }
}

2. Производитель:
package com.hongri.designpattern.producer_consumer;

import java.util.Random;

/**
 * 生产者
 */
public class Producer implements Runnable {
    
    
    private String name;
    private SyncStack stack;

    public Producer(String name, SyncStack stack) {
    
    
        this.name = name;
        this.stack = stack;
    }

    @Override
    public void run() {
    
    
        while (true) {
    
    
            int value = new Random().nextInt(100);
            stack.push(name, value);
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

3. Потребители:
package com.hongri.designpattern.producer_consumer;

/**
 * 消费者
 */
public class Consumer implements Runnable{
    
    
    private String name;
    private SyncStack stack;

    public Consumer(String name, SyncStack stack) {
    
    
        this.name = name;
        this.stack = stack;
    }

    @Override
    public void run() {
    
    
        while (true) {
    
    
            try {
    
    
                Thread.sleep(3000);
                int val = stack.pop(name);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

4. Звоните:
        SyncStack stack = new SyncStack();
        Producer producer1 = new Producer("Producer1", stack);
        Producer producer2 = new Producer("Producer2", stack);
        Producer producer3 = new Producer("Producer3", stack);

        Consumer consumer1 = new Consumer("Consumer1", stack);
        Consumer consumer2 = new Consumer("Consumer2", stack);
        Consumer consumer3 = new Consumer("Consumer3", stack);

        new Thread(producer1).start();
        new Thread(producer2).start();
        new Thread(producer3).start();
        new Thread(consumer1).start();
        new Thread(consumer2).start();
        new Thread(consumer3).start();



Результаты теста:вставьте сюда описание изображения


Ссылка:
Обзор шаблона проектирования Java
Приложение шаблона проектирования производителя-потребителя в пуле потоков

Supongo que te gusta

Origin blog.csdn.net/u012440207/article/details/122577577
Recomendado
Clasificación