Java デザイン パターンのプロデューサー/コンシューマー パターン

1. 生産者/消費者パターンとは?

特定のモジュールは、別のモジュールによって処理されるデータの生成を担当します (ここでのモジュールは一般化されており、クラス、関数、スレッド、プロセスなどにすることができます)。データを生成するモジュールはプロデューサーと呼ばれ、データを処理するモジュールはコンシューマーと呼ばれます。生産者と消費者の間に緩衝地帯が追加され、これを倉庫と呼び、生産者は倉庫に商品を入れる責任があり、消費者は倉庫から商品を取り出す責任があります.モデルです。

構造図は次のとおりです。


第二に、生産者消費者モデルの利点:

1. デカップリング:

バッファーが存在するため、プロデューサーとコンシューマーの間に直接的な依存関係はなく、結合の程度が減少します。

2. 同時実行をサポート:

プロデューサとコンシューマは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 デザイン パターンの概要
Producer Consumer デザイン パターン スレッド プールでのアプリケーション

おすすめ

転載: blog.csdn.net/u012440207/article/details/122577577