Java并发编程中的生产者与消费者模型简述
作者:低调小一 发布时间:2023-02-16 20:33:18
标签:Java,并发
概述
对于多线程程序来说,生产者和消费者模型是非常经典的模型。更加准确的说,应该叫“生产者-消费者-仓库模型”。离开了仓库,生产者、消费者就缺少了共用的存储空间,也就不存在并非协作的问题了。
示例
定义一个场景。一个仓库只允许存放10件商品,生产者每次可以向其中放入一个商品,消费者可以每次从其中取出一个商品。同时,需要注意以下4点:
1. 同一时间内只能有一个生产者生产,生产方法需要加锁synchronized。
2. 同一时间内只能有一个消费者消费,消费方法需要加锁synchronized。
3. 仓库为空时,消费者不能继续消费。消费者消费前需要循环判断当前仓库状态是否为空,空的话则消费线程需要wait,释放锁允许其他同步方法执行。
4. 仓库为满时,生产者不能继续生产,生产者生产钱需要循环判断当前仓库状态是否为满,满的话则生产线程需要wait,释放锁允许其他同步方法执行。
示例代码如下:
public class Concurrence {
public static void main(String[] args) {
WareHouse wareHouse = new WareHouse();
Producer producer = new Producer(wareHouse);
Consumer consumer = new Consumer(wareHouse);
new Thread(producer).start();
new Thread(consumer).start();
}
}
class WareHouse {
private static final int STORE_SIZE = 10;
private String[] storeProducts = new String[STORE_SIZE];
private int index = 0;
public void pushProduct(String product) {
synchronized (this) {
while (index == STORE_SIZE) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storeProducts[index++] = product;
this.notify();
System.out.println("生产了: " + product + " , 目前仓库里共: " + index
+ " 个货物");
}
}
public synchronized String getProduct() {
synchronized (this) {
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String product = storeProducts[index - 1];
index--;
System.out.println("消费了: " + product + ", 目前仓库里共: " + index
+ " 个货物");
this.notify();
return product;
}
}
}
class Producer implements Runnable {
WareHouse wareHouse;
public Producer(WareHouse wh) {
this.wareHouse = wh;
}
@Override
public void run() {
for (int i = 0; i < 40; i++) {
String product = "product" + i;
this.wareHouse.pushProduct(product);
}
}
}
class Consumer implements Runnable {
WareHouse wareHouse;
public Consumer(WareHouse wh) {
this.wareHouse = wh;
}
@Override
public void run() {
for (int i = 0; i < 40; i++) {
this.wareHouse.getProduct();
}
}
}


猜你喜欢
- 循环例子:while循环和do…while循环whlie(条件语句) {循环体}//先进行条件语句的判断,再进行循环体do {循环体}whl
- 今天记录一下验证码的实现,希望能够帮助到大家!首先我们看一下实现的效果:此验证码的实现没有用到太多的插件,话不多说直接上代码,大家拿过去就可
- 找入口对 Spring 有一定基础的同学一定知道,请求入口是DispatcherServlet,所有的请求最终都会落到doDispatch方
- 本文实例为大家分享了java * 实现在线人数统计的具体代码,供大家参考,具体内容如下1.在工程中创建监听类SessionListener
- iText下载页面: http://sourceforge.net/projects/itext/files/1.创建简单的PDF文件pac
- 获取e.printStackTrace()打印的信息某些情况下,我们需要获取应用打印的异常信息,这时就可以借助StringWriter和Pr
- 在前面介绍的代码中有使用特性,这些特性都是Microsoft定义好的,作为.NET Framework类库的一部分,许多特性都得到了C#编译
- 1. 开方:Math.sqrt(x);2. x的a方:Math.pow(x,a);3. 绝对值:Math.abs(x);4. BigInte
- 今天看到一个银行的APP上面的loadingview 挺好的,就尝试着自己实现,觉得很简单,但自己实现起来还是发现了一些问题。Loading
- 一、APP端调用1、注册广播监听查找结果//蓝牙发现设备和查找结束广播IntentFilter intentFilter = new Int
- 最近单位又有一个新Java项目。涉及到扫码登录。之前项目使用的是 ajax轮询的方式。感觉太low了。所以这次用webSocket的方式进行
- 一 技术发展技术的创新和发展都是为了解决一类问题二 框架设计Spring Framework 6大模块三 Spring AOP详解循环依赖问
- 本文实例讲述了Android编程实现全局获取Context及使用Intent传递对象的方法。分享给大家供大家参考,具体如下:一、全局获取 C
- 实现以下功能:验证字符串是否由正负号(+-)、数字、小数点构成,并且最多只有一个小数点验证字符串是否仅由[0-9]构成验证字符串是否由字母和
- 本文实例讲述了Java String类简单用法。分享给大家供大家参考,具体如下:一 String类的实例化方式1 代码public clas
- 上篇文章中介绍了聊天功能,这里介绍通讯录是如何实现的。首先要加载公司的所有部门,树形结构,然后点击进入部门的人员列表,点击人员能查看详细信息
- 1.Context的应用Context在启动协程模式中就已经遇到过叫CoroutineContext,它的意思就是协程上下文,线程的切换离不
- Android程序中,Tab标签窗口是一种常用的UI界面元素。它的实现主要是利用了TabHost类。TabHost说明TabHost是一个标
- 一、常用操作NextDouble():返回0-1.0之间的随机数Next():返回非负随机整数(0-216)Next(i):返回一个小于i的
- 最近做了一个使用 C# 写了一个发送邮件的windows 服务,在这里记录一下。首先使用 Visual Studio 2015 创建一个 w