设计模式之多线程分工模式--- 生产-消费者模式

发布时间:2024年01月16日

系列文章目录

设计模式之避免共享的设计模式Immutability(不变性)模式
设计模式之并发特定场景下的设计模式 Two-phase Termination(两阶段终止)模式
设计模式之避免共享的设计模式Copy-on-Write模式
设计模式之避免共享的设计模式 Thread-Specific Storage 模式
设计模式之多线程版本的if------Guarded Suspension模式
设计模式之多线程版本的if------Balking模式
设计模式之多线程分工模式— Thread-Per-Message模式
设计模式之多线程分工模式—Worker Thread模式



前言

  • Worker Thread模式类比的是工厂里车间工人的工作模式。但其实在现实世界,工厂里还有一种流水线的工作模式,类比到编程领域,就是生产者 - 消费者模式。
  • 生产者 - 消费者模式的核心是一个任务队列,生产者线程生产任务,并将任务添加到任务队列中,而消费者线程从任务队列中获取任务并执行。
  • 消息队列(MQ)可以被看作是一种生产者-消费者模式的实现。MQ充当了一个中间件的角色,用于解耦消息的生产者和消费者,使它们能够异步地进行通信。

应用场景

场景

  1. 消息队列:生产者-消费者模式常用于消息队列的实现中。生产者负责向队列中添加消息,而消费者则负责从队列中取出消息进行处理。

  2. 数据库连接池:生产者-消费者模式可以用于管理数据库连接池。生产者负责创建新的数据库连接,将其添加到连接池中,而消费者则从连接池中获取连接并执行数据库操作。

  3. 线程池:线程池的任务队列就是一个典型的生产者-消费者场景。生产者向任务队列中添加任务,而消费者则从队列中获取任务并执行。

  4. 缓存系统:生产者-消费者模式可以用于缓存系统,生产者负责向缓存中添加数据,而消费者则从缓存中获取数据。

  5. 计算任务分发:在分布式系统中,生产者-消费者模式可以用于将计算任务分发到各个工作节点,生产者负责创建任务并将其添加到任务队列中,而消费者则从队列中获取任务并执行。

样例

import java.util.concurrent.*;

/**
 * @author yang
 * @version 1.0.0
 * @date 2024/1/16 18:18
 */
public class ProducerConsumerExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(2);
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
        Producer producer = new Producer(queue);
        Consumer consumer = new Consumer(queue);
        executor.submit(producer);
        executor.submit(consumer);
        executor.shutdown();
    }
}
class Producer implements Runnable {
    private BlockingQueue<Integer> queue;
    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            try {
                System.out.println("生产>>>>>数据" + i);
                queue.put(i);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Consumer implements Runnable {
    private BlockingQueue<Integer> queue;
    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }
    @Override
    public void run() {
        while (true) {
            try {
                int value = queue.take();
                System.out.println("数据>>>>消费" + value);
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


优缺点

优点

  1. 解耦性:生产者和消费者之间通过中间的缓冲区(队列)进行通信,从而实现了解耦,生产者和消费者可以独立进行处理,提高了系统的灵活性和可维护性。

  2. 并发控制:生产者-消费者模式可以有效地控制多个线程之间的并发访问,通过合理地控制缓冲区的大小和生产者、消费者的速度,可以避免生产者和消费者之间的竞争和阻塞。

  3. 提高系统吞吐量:通过并行处理和异步通信,生产者-消费者模式可以提高系统的吞吐量和性能。

  4. 消除生产者与消费者之间速度差异:即削峰填谷

缺点

  1. 复杂性:实现生产者-消费者模式需要考虑到并发访问、同步和互斥控制等问题,增加了系统的复杂性。

  2. 容易出现问题:由于生产者和消费者之间的异步通信,可能导致一些问题的出现,比如数据一致性问题、死锁、过饱等,并发编程中的典型问题会增加对开发者的要求。

  3. 性能问题:如果生产者生产的速度远大于消费者的处理速度,可能导致队列满,从而影响系统的响应速度,需要设计合理的流量控制和调整。

文章来源:https://blog.csdn.net/weixin_44859605/article/details/135626093
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。