Java多线程_生产者消费者模式1
生产者消费者模型
具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品。生产消费者模式如下图。(图片来自网络,侵删!)

生产者消费者模型的实现
生产者是一堆线程,消费者是另一堆线程,内存缓冲区可以使用List数组队列,数据类型只需要定义一个简单的类就好。关键是如何处理多线程之间的协作。这其实也是多线程通信的一个范例。
在这个模型中,最关键就是内存缓冲区为空的时候消费者必须等待,而内存缓冲区满的时候,生产者必须等待。其他时候可以是个动态平衡。值得注意的是多线程对临界区资源的操作时候必须保证在读写中只能存在一个线程,所以需要设计锁的策略。
具体实现:
import java.util.LinkedList;
public class ProductorConsumerDemo {
LinkedList<Integer> lists = new LinkedList<>(); // 定义存放物品的仓库
int size = 10; // 定仓库的大小
// 生产物品
public synchronized void add(Integer i) { // 这里对临界资源的访问贯穿了整个方法,synchronized可以直接加到方法上
if (lists.size() == size) { // 首先判断还能不能生产? 也就是容量到了size吗?
try {
this.wait(); // 不需要的生产 ,就等待
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
lists.add(i); // 把生产出来的物品放进仓库
this.notifyAll(); // 唤醒消费者线程来消费
}
}
// 消费
public synchronized int remove() {
if (lists.size() == 0) { // 判断有没有物品
try {
this.wait(); // 如果没有物品就等待, 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
int i = lists.removeFirst(); // 有物品,就拿走一个
if (lists.size() == 0) // 如果拿到了最后一个
{
this.notifyAll(); // 通知生产者生产物品
}
return i;
}
return -1;
}
public static void main(String[] args) {
ProductorConsumerDemo pcd = new ProductorConsumerDemo();
new Thread(new Runnable() {
int count = 1;
@Override
public void run() {
while (true) {
int i = count++;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
pcd.add(i);
System.out.println(Thread.currentThread().getName() + " 生产了第 " + i + " 个物品,还有" + pcd.lists);
}
}
}, "生产者 ").start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
Thread.sleep(110);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 消费了第 " + pcd.remove() + "个物品");
}
}
}, "消费者 ").start();
}
}
结果:

这种方式很麻烦,在我的下一条博客中将介绍一种简单的实现方法。
Java多线程_生产者消费者模式1的更多相关文章
- Java多线程_生产者消费者模式2
在我的上一条博客中,已经介绍到了多线程的经典案列——生产者消费者模式,但是在上篇中用的是传统的麻烦的非阻塞队列实现的.在这篇博客中我将介绍另一种方式就是:用阻塞队列完成生产者消费者模式,可以使用多种阻 ...
- Java多线程-----实现生产者消费者模式的几种方式
1 生产者消费者模式概述 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题.生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理 ...
- 【多线程】java多线程实现生产者消费者模式
思考问题: 1.为什么用wait()+notify()实现生产者消费者模式? wait()方法可以暂停线程,并释放对象锁 notify()方法可以唤醒需要该对象锁的其他线程,并在执行完后续步骤,到了s ...
- JAVA多线程之生产者 消费者模式 妈妈做面包案例
创建四个类 1.面包类 锅里只可以放10个面包 ---装面包的容器2.厨房 kitchen 生产面包 和消费面包 最多生产100个面包3.生产者4消费者5.测试类 多线程经典案例 import ja ...
- Java多线程编程——生产者-消费者模式(1)
生产者-消费者模式在生活中非常常见.就拿我们去餐馆吃饭为例.我们会遇到以下两种情况: 1.厨师-客人 如下图所示,生产者.消费者直接进行交互. 生产者生产出产品后,通知消费者:消费者消费后,通知生产者 ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- 【多线程】--生产者消费者模式--Lock版本
在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...
- Java设计模式之生产者消费者模式
Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...
随机推荐
- ES6 class继承的简单应用
class的好处就是让继承的实现更加简单,语法简单,理解起来也不复杂,但是现在只能做测试使用,项目中需要用Babel工具. <!DOCTYPE html> <html> < ...
- logging日志基础示例
import logging logger = logging.getLogger() # 获取日志对象 logfile = 'test.log' hdlr = logging.FileHandler ...
- Python 爬取网易云歌手的50首热门作品
使用 requests 爬取网易云音乐 Python 代码: import json import os import time from bs4 import BeautifulSoup impor ...
- 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论
LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...
- dp的本质
什么是真正的dp?有什么特点?怎么来搞. 最近遇到了一些以前的题目发现没有好好的理解就直接写了 大多都是书上的算法并不是自己真正的理解. 1 关于背包 我总结一下 可能 有助于对模型的更快发现 01 ...
- 剑指 Offer 57 - II. 和为s的连续正数序列
本题 题目链接 题目描述 我的题解 方法三双100%, 方法一 适合范围广 方法一:双指针(也叫 滑动窗口) 思路分析 用两个指针i和表示当前枚举到的以i为起点,j为终点的区间,sum表示[i,j]的 ...
- lamp架构搭建
目录 1. LAMP架构介绍 2.web服务器工作流程 2.1 cgi与fastcgi 2.2 httpd与php结合的方式 2.3 web工作流程 3. lamp平台搭建 3.1 安装httpd 3 ...
- 实验05——java算术运算符减法
package cn.tedu.demo; import java.math.BigDecimal; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ver ...
- springboot集成mongodb实现动态切换数据源
主要实现原理,利用spring的aop 在切入点执行db操作之前 将数据库切换: 本例子采用aop在controller进行拦截 拦截到MongoTemplate.class 切换数据源后重新放回去 ...
- 博客主题推荐——复杂&简单
首先感谢原作者cjunn提供的主题autm,以下配置都基于此主题设定.很多小伙伴喜欢现在的样式,分享如下.只需简单几步即可. 如果你想使用本博客主题样式,并希望能得到远程推送更新,只需查看 快速部署. ...