Java生产消费者模型介绍和写法

基于LinkedBlockingQueue来实现生产者和消费者模型Demo       生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。 解决生产者/消费者问题的方法可分为两类: 采用某种机制保护生产者和消费者之间的同步; 在生产者和消费者之间建立一个管道。 第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用... 阅读详情

一.模型定义

1.生产者持续生产,直到缓冲区满,阻塞;2.缓冲区不满后,继续生产消费者持续消费,直到缓冲区空,阻塞;3.缓冲区不空后,继续消费生产者可以有多个,消费者也可以有多个

二.几种写法

1.常规写法:

/**
 * @author Seven 消费者线程 可能有多个消费者
 *
 */
public class Consumer extends Thread{

	Repo repo;
	public Consumer(Repo repo) {
		super();
		this.repo = repo;
	}
	
	@Override
	public void run() {
		super.run();
		while(true) {
			repo.remove();
			try {
				Thread.sleep(5000); //凸显生产线程超过额定数量时阻塞
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}

/**
 * @author Seven 生产者线程
 *
 */
public class Producer extends Thread{
	Repo repo;
	public Producer(Repo repo) {
		super();
		this.repo = repo;
	}



	@Override
	public void run() {
		super.run();
		
		while(true) {
			repo.add();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		
	}
}




/**
 * @author Seven 仓库类
 *
 */
public class Repo {

	int capacity = 10; // 仓库最大容量

	List<Integer> repsList = new ArrayList<Integer>(); // 共享数据区

	/**
	 * 同步方法,向共享数据区添加数据,如果当前数据区等于仓库最大容量, 需要让生产线程等待执行
	 * 
	 */
	public synchronized void add() {
		String name = Thread.currentThread().getName();
		if (repsList.size() == 10) {
			// 最大容量,等待
			try {
				System.out.println(name + "添加货物失败" + ",已经超过仓库最大容量了,线程阻塞中,需要等待添加。。。。。");
				wait();
				System.out.println("线程等待后执行》》》》》》》》》》》");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} else {
				repsList.add(1);
				System.out.println(name + "添加货物成功");
				System.out.println("只要有货物,生产者就唤醒消费线程获取货物《《《");
				notifyAll();// 唤醒在此对象监视器上等待的线程
		
			
		}
	

		
	}

	/**
	 * 同步方法,移除共享数据区第一条数据,如果没有数据,则让其线程等待
	 */
	public synchronized void remove() {
		String name = Thread.currentThread().getName();
		if (repsList.size() == 0) {
			try {
				notifyAll();
				System.out.println(name + "消费货物失败" + ",仓库已经没有货物了,需要生产者生产货物。。。");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} else {
			repsList.remove(0);
			System.out.println(name + "消费货物成功");
		}
	}

}

package com.ts.consumer;

/**
 * @author Seven 测试类
 *
 */
public class TsMain {

	public static void main(String[] args) {
		Repo repo=new Repo();
		Producer p=new Producer(repo);
		p.setName("生产者线程");
		Consumer c1=new Consumer(repo);
		Consumer c2=new Consumer(repo);
		c1.setName("小明消费者");
		p.start();
		c1.start();

	}
}

输出日志:
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
小明消费者消费货物成功
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物成功
只要有货物,生产者就唤醒消费线程获取货物《《《
生产者线程添加货物失败,已经超过仓库最大容量了,线程阻塞中,需要等待添加。。。。。

2.用阻塞队列实现

生产者:

public class Producer extends Thread{

	public Producer(BlockingQueue bq) {
		super();
		this.bq = bq;
	}
	BlockingQueue bq;
	@Override
	public void run() {
		super.run();
		while(true) {
			try {
				System.out.println("生产数据");
				bq.put(1);//put()方法:类似于我们上面的生产者线程,容量达到最大时,自动阻塞。
				Thread.sleep(300);
			} catch (InterruptedException e) {
				System.out.println("生产数据异常");
				e.printStackTrace();
			}
		}
	}


}

消费者:

public class Consumer extends Thread{

	BlockingQueue bq;

	public Consumer(BlockingQueue bq) {
		super();
		this.bq = bq;
	}
	@Override
	public void run() {
		super.run();
		while(true) {
			try {
				System.out.println(getName()+"取出"+bq.take());//take()方法:类似于我们上面的消费者线程,容量为0时,自动阻塞。
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				System.out.println("取出异常");
				e.printStackTrace();
			}
		}
	}
}

测试代码

public class TsMain {

	public static void main(String[] args) {
		BlockingQueue bq=new LinkedBlockingQueue(10);
		Consumer c=new Consumer(bq);
		c.setName("c1");
		Producer p=new Producer(bq);
		Consumer c2=new Consumer(bq);
		c2.setName("c2");
		c.start();
		p.start();
		c2.start();
	}
}

测试打印
生产数据
c1取出1
生产数据
c2取出1
生产数据
生产数据
c1取出1
生产数据
c2取出1
生产数据
生产数据
c1取出1
生产数据
c2取出1
生产数据
生产数据
c1取出1
生产数据
c2取出1
生产数据
生产数据
生产数据
c1取出1
生产数据
c2取出1
生产数据
生产数据

眼动数据分析基础_AOI分析动态刺激物 如果您正在研究人们对如视频、动画等动态刺激物的视觉行为,动态AOI工具可为您提供类似静态AOI工具对于图片及其他静止刺激物分析的同样功能。创建和编辑动态AOI的过程和静态AOI相似。 关于动态AOI工具的使用,有几点非常重要: 多个看到相同线性动态刺激物的用户的眼动数据叠加是有价值的; 动态AOI不能用于非线性动态记录的分析; 动态AOI不能用于静态刺激物,如图片的分析; 动态AOI可以被开启、关闭、移动、调整大小及跟踪相关分析对象 首先,我们来定义两种不同的动态刺激物:线性动态刺激物(LDS),是指固 阅读详情

相关推荐

地质工程师必备:Dips软件从数据导入到主结构面分析的完整流程解析

本文详细解析了地质工程师使用Dips软件进行主结构面分析的完整流程。从数据准备与导入、结构面分组与扇形区划分,到主结构面计算与工程解读,系统阐述了如何将野外节理数据转化为控制岩体稳定性的关键信息。重点介绍了利用等值线图识别优势组、计算统计主值及其置信椭圆,并强调了地质判断与工程应用结合的重要性。

table的专栏 341

【Java 基础篇】Java 生产者-消费者模式详解

生产者-消费者模式是一种经典的多线程设计模式,用于解决多个线程之间的数据共享和协作问题。在生产者-消费者模式中,有两类线程:生产者线程和消费者线程。它们之间通过共享一个缓冲区(或队列)来协作,生产者将数据放入缓冲区,消费者从缓冲区取出数据并进行处理。生产者-消费者模式的主要目标是实现生产者和消费者之间的解耦,使它们可以独立地进行工作,从而提高系统的性能和可维护性。首先,我们定义一个有界缓冲区,使用来实现,它是 Java 并发包中提供的一个有界队列。} }} }} }

繁依Fanyi的博客 2556

超声波 vs 红外 vs 激光雷达:扫地机器人避障传感器选型指南(实测对比)

本文深入对比了扫地机器人三种主流避障传感器——超声波、红外与激光雷达的核心原理与实测表现。文章基于成本、精度、环境适应性等关键指标,提供了清晰的选型决策树和典型场景配置方案,旨在帮助开发者与爱好者根据项目需求与预算,构建高效可靠的机器人避障系统。

h0i1j2k3l的博客 690

Java实现生产者消费者问题

生产者-消费者问题是计算机科学中经典的同步问题之一,它描述了多个线程在共享数据的情况下如何协同工作。该问题通常涉及到一个共享缓冲区,其中生产者线程生成数据并将其放入缓冲区,而消费者线程从缓冲区中取出数据并对其进行处理。生产者和消费者线程必须协同工作,以避免竞态条件和死锁等问题。以上为通过Java代码实现解决生产消费者问题的实例,通过本实例希望大家能学会如果解决此问题,学会如何数据共享时,各个线程协同工作。

无简介 6120

FTP新手必看:vsftpd 530登录错误的8种实战解决方案(附详细配置步骤)

本文针对FTP服务配置中常见的vsftpd 530登录错误,提供了8种实战解决方案。从理解错误本质入手,系统性地排查用户列表策略、PAM认证、系统黑名单、Shell限制、目录权限及DNS解析等问题,并附有详细的配置步骤与命令,帮助新手快速定位并解决登录失败难题。

ik678901的博客 696

新出的智谱GLM-4.7很牛逼?

Zhipu AI(智谱)最近发布的 GLM-4.7 再次刷新了开源大模型的天花板。作为一款约 400B 参数规模的 MoE 模型,它不仅在传统的代码与推理任务上超越了 DeepSeek-V3.2 和 Kimi-K2 等强力对手,更通过**“保留思考(Preserved Thinking)”和“交错思考(Interleaved Thinking)”**等架构级创新,重新定义了 Agentic Workflow 的设计范式。

kakaZhui的博客 2397

Java中的生产者/消费者模型

生产者-消费者模型(Producer-Consumer problem)是一个非常经典的多线程并发协作的模型。比如某个模块负责生产数据,而另一个模块负责处理数据。产生数据的模块就形象地被称为生产者;而处理数据的模块,则被称为消费者。生产者和消费者在同一段时间内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。

u010257931的博客 6813

从零搭建一个AF架构项目:基于TIA Portal V19和S7-PLCSIM的仿真调试全流程

本文详细介绍了如何在TIA Portal V19环境中从零搭建西门子Automation Framework(AF架构)项目,包括环境准备、硬件组态、核心组件创建、项目架构分层实现以及仿真调试全流程。通过模块化编程和标准化接口设计,AF架构显著提升工业自动化项目的开发效率和维护便利性,特别适合S7-1500系列PLC的应用开发。

weixin_29313547的博客 675

Java生产者和消费者模型的5种实现方式

生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。 生产者消费者.png 现在用四种方式来实现生产者消费者模型 wait()和notify()方法的实现 这也是最简单最基础的实现,缓冲区满和为空时都调用wait()方法等待,当生产者生产了一个产品或者消费者消费了一个产品之后会唤醒所有线程。 /** * 生产者和消费者,wai..

林中静月下仙的博客 863

Quantum Espresso实战进阶:HSE混合泛函在能带计算中的精准应用

本文深入探讨了在Quantum Espresso中应用HSE混合泛函进行高精度能带计算的实战方法。针对传统DFT方法低估半导体带隙的问题,HSE通过混合精确交换能,显著提升计算精度。文章详细讲解了从输入文件配置、参数设置(如nqx网格、exxdiv_treatment)、到自洽与非自洽计算流程,以及结果可视化与对比的全过程,并提供了关键的调优与避坑指南,助力实现从PBE到HSE的精准进阶。

weixin_28363123的博客 226

Dify智能体开发:大语言模型(LLM)问题分类

通过定义分类描述,问题分类器能够根据用户输入,使用 LLM 推理与之相匹配的分类并输出分类结果,向下游节点提供更加精确的信息。

王国平的博客 2249

Java实现生产者消费者模型的三种方式

生产者-消费者模型是一种多线程并发模型,其中生产者线程负责生产数据,并将数据放入共享的缓冲区中,而消费者线程则负责从缓冲区中取出数据并进行处理。

gbj2020的博客 2756

ArcGIS Pro 制作这种地图海报

ArcMap 版本与 ArcGIS Pro 版本的制图功能相差太多,无论从美观上还是制图效率都远远优于 ArcMap,用了一段时间的 ArcGIS Pro ,真心推荐有条件的大家赶紧试一试!一个软件也能搞定一张不错的海报哦!----吐槽:好的设计真的是门花时间的活,这个教程大概花了我7小时左右,我都忘了我自己教程中截图多少张了!(可能是我速度太慢了)测试数据:阿里云盘分享-----北极海冰数据.https://www.aliyundrive.com/s/SUhsnqfkmXh。

J_Giser的博客 1430

【Java总结】生产者消费者模型

生产者消费者模型主要结构如下,是一个典型的线程同步的案例。下面就来使用java做几种线程同步的方式来实现以下该模型 确保一个生产者消费者模型的稳定运行的前提有以下几个 生成者应该具备持续生成的能力 消费者应该具备持续消费的能力 生产者的生成和消费消费有一定的阀值,如生成总量到100需要停止生产,通知消费;消费到0的时候停止消费开始生产; wait,notify方案阻塞队列的实现Reentr...

zhujohnle的专栏 8978

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java生产者消费者模型

前言 生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一个存储空间,生产者往存储空间中添加产品,消费者从存储空间中取走产品,当存储空间为空时,消费者阻塞,当存储空间满时,生产者阻塞。 基于synchronized配合wait()和notify()方法的实现 这也是最简单最基础的实现,缓冲区满和为空时都调用wait()方法等待,当生产者生产了一个产品或者消费者消费了一个产品之后会唤醒所有线程。 public class Test...

有个疙叫瘩儿的博客 5273

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Java中生产者和消费者总结

生产者和消费者问题是线程模型中的经典问题,生产者和消费者在同一时间段共用同一个存储空间,这个存储空间是一个缓冲区的仓库,生产者可以将产品放入仓库,消费者可以从仓库中取出产品。 ...

Joseph的博客 3773

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

生产者消费者模型java实现

做题的时候遇到了生产者消费者问题,这个问题可以说是线程学习的经典题目了,就忍不住研究了一波。它描述是有一块缓冲区(队列实现)作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。在Java中这个数组线程阻塞的问题,多个用户同时发送多个请求,怎么保证不发生线程死锁,是我们要考虑的问题。 生产者消费者模式说明: 1.生产者只在仓库未满时进行生产,仓库满时生产者进程被阻塞; 2.消费者...

Fighting的博客 1万+

生产者消费者和仓储模型案例

产品类 - Cake(brand、price、datetime) 仓库类 - Store(maxCapacity、curCapacity、list) 生产者线程 - Producer 消费者线程 - Consumer 注意:先生产的先卖出 -- 队列模式。1.多个线程(生产者线程、消费者线程)操作同一个资源(产品类的对象) 2.多个产品之间来回切换(华为 <--> 小米) null -- 0.0 华为 -- 0.0 小米 -- 3999 华为 -- 1999 脏数据的解决思路:加锁 3.生产一个消费一个。

m0_68761186的博客 1674

Java的生产者消费者模型

前言 学完了线程后,我又去找了一些线程相关的练习题来练手,其中印象最深的就是生产者消费者模型这一块,为什么呢,因为它每一篇练习题里都有,开始没看懂,后面就去仔细研究了一下,哦,原来是这样,好像是懂了,那就来写写博客吧。哈哈哈…… 什么是生产者消费者模型 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲

Andy-ZhangSir的博客 1695

Java实现生产者消费者模型

Java实现生产者消费者模型 生产者消费者模型,是一般面试题都会考的,下面介绍使用ReetrantLock实现 生产者消费者模型。 定义一个ReentrantLock锁,同时new出两个condition,一个控制队满,一个 控制队空 //生产者 消费者 import java.util.LinkedList; import java.util.Queue; import java.util....

zycxnanwang的博客 1024

Java生产者-消费者-仓储 模型

Java生产者消费者模型 文章目录Java生产者消费者模型介绍理解规则分析预备知识代码实现思路实现总结 介绍 理解 现有如下需求,需要用Java实现以下操作流程: 多个蛋糕师生产蛋糕,多个消费者消费蛋糕; 蛋糕的最大仓库是固定的 蛋糕以先进先出原则出售,先生产的蛋糕先被出售,后生产的蛋糕后出售 若要实现这个过程,要借助Java线程的并发写作来做。 生产着消费者模型,完整称作生产者-消费者-...

大胡子康贝勒爷 1258

java简单的实现生产者消费者模型

今日看到一篇以厨师和服务员为例的,生产者消费者模型的解释,想来就顺手实现一下。首先生产者不断地生产数据就好比多个厨师不断地做菜,消费者不断地消费数据就如同服务员不断地上菜。厨师将做好的菜放到窗口等待,就如同生产者将数据放进队列后等待一样。那么我们可以简单的建立以下模型: (1)Food模型 public class Food { private static int counter...

renchunlin66的博客 998

java并发之生产者消费者模型

生产者和消费者模型是操作系统中经典的同步问题。该问题最早由Dijkstra提出,用以演示它提出的信号量机制。经典的生产者和消费者模型的描述是:有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费。为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区中;消费者进程可从一个缓冲区中取走产品去消费。尽管所有的生产者进程和消费者

每天进步一点点 3869

【Java】一文搞懂生产者和消费者模型

阻塞队列、消息队列、消息队列的作用、阻塞队列和生产者消费费者模型的实现

qq_43243800的博客 1034

Java 多个生产者和多消费者

Java 多个生产者和多个消费者 代码如下: package 测试; import java.util.ArrayList; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /...

cwl110120的博客 1266

Java实现生产者——消费者模型

对多线程同步问题一直了解不是很深刻,找了生产者消费者模型来试验了一下。不知道正确与否,初步实验了一下好像是正确的,如有错误请指正。 生产者——消费者模型是这样的: 有M个生产者不断的想生产线上放置产品。而有N个消费者从生产线上将产品拿出来。实现这一过程。 代码如下所示: package concurrency; import java.util.Random; import

Solidfish的专栏 1962
上一篇: lesson8:java的集合类
下一篇: 设计模式之观察者模式
android_seven
博客等级 码龄11年 8粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值