Java实现生产者-消费者模式的方案

文章探讨了生产者消费者模式的两种实现方案。单线程和多线程生产者方案中,提到了线程安全和速度控制的问题,建议使用ScheduledThreadPoolExecutor避免忙等待和死锁。消费者则通过多线程和ThreadPoolExecutor进行数据消费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现模式

生产者生产数据,消费者直接消费数据

在这里插入图片描述

生产者生产数据放入队列,消费者消费队列中的数据

在这里插入图片描述

生产者实现方案

单线程实现方案

将生产数据逻辑拆分为多个小task,task使用线程池处理。需要注意生产数据的速度和消费数据速度

多线程实现方案

方案一

‘ProducerThreadNum’:生产者的线程数量,Thread.sleep(3000)控制生产数据的速度,确保生产数据的速度<=消费数据的速度

    for (int i = 1; i <= ProducerThreadNum; i++) {
            new Thread(() -> produce().start();
            try {
                //控制生产数据的速度
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

存在的问题:编译器出现Thread.sleep() in a loop, probably busy-waiting的提示。该写法可能造成忙等待和死锁的问题。

方案二

使用ScheduledThreadPoolExecutor 定时线程实现周期执行任务。producerCorePoolSize核心线程池数量,2表示任务执行周期。使用定时任务线程池很好的避免了出现方案一种可能出现的两个问题

  ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(
               producerCorePoolSize,
                new ThreadFactoryBuilder().setNameFormat("producer-pool-%d").build(),
                new CallerRunsPolicy());
        scheduledThreadPoolExecutor.scheduleAtFixedRate(
                () -> produce(), 0, 2, TimeUnit.SECONDS);

消费者实现方案

使用多线程消费数据,示例如代码:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
                                   corePoolSize, 
                                   maxPoolSize, 
                                   180, 
                                   TimeUnit.SECONDS,
                                   new LinkedBlockingQueue<>(1024),
                                   new ThreadFactoryBuilder().setNameFormat("consumer-pool-%d").build(),
                new CallerRunsPolicy());
 consumeExecutorService.submit(() -> consume())

注:个人总结。有错误之处,欢迎大佬们指证。如关于生产-消费模式有更好的实现方案,欢迎一起讨论学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值