java多线程系列15 设计模式 生产者 - 消费者模式
生产者-消费者
生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现
在该模式中 通常会有2类线程,消费者线程和生产者线程
生产者提交用户请求 消费者负责处理生产者提交的任务,在消费者和生产者之间共享内存缓存区进行通信
常见的实现 可以 通过 wait/notifyAll来 或者 阻塞队列来实现 下面我来演示下通过 wait/notifyAll 来实现。。。
下面是代码演示
public class Storage<T> {
LinkedList<T> list = new LinkedList<>();
private Integer maxSize;
public Integer getMaxSize() {
return maxSize;
}
public void setMaxSize(Integer maxSize) {
this.maxSize = maxSize;
}
public T consumer() {
synchronized (list) {
if (list == null || list.size() == 0) {
try {
System.out.println(Thread.currentThread().getName() + " 等待 ");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
T t = list.remove();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 消费 " + t);
if (list.size() == 0) { // 消费完了 通知生产者 继续生产
list.notifyAll();
}
return t;
}
}
return null;
}
public void producer(T t) {
synchronized (list) {
if (list.size() == maxSize.intValue()) {
System.out.println(Thread.currentThread().getName() + " 仓库已满 暂停生产 ");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
list.add(t);
System.out.println(Thread.currentThread().getName() + " 生产 " + t);
list.notifyAll();
}
}
}
public static void main(String[] args) {
Storage<Integer> storage = new Storage<>();
storage.setMaxSize(5);
AtomicInteger numberGenarnate = new AtomicInteger(0);
ExecutorService consumerService = Executors.newCachedThreadPool();
for (int i = 0; i < 3; i++) {
Runnable run = new Runnable() {
@Override
public void run() {
while (true) {
storage.consumer();
}
}
};
consumerService.submit(run);
}
for (int i = 0; i < 1; i++) {
Runnable run = new Runnable() {
@Override
public void run() {
while (true) {
storage.producer(numberGenarnate.incrementAndGet());
}
}
};
consumerService.submit(run);
}
consumerService.shutdown();
}
}
运行结果如下

总结:对于消费者生产者模式 要理解其思想。实际开发中。mq(消息队列)就是典型的应用。
对于mq这里多说几句,关于技术选型:::
Mq适用于生产者生产很多 消费者处理不过来的情况 。如果消费者处理能力很强,就不要用mq了,直接使用nio框架(mina or netty)
java多线程系列15 设计模式 生产者 - 消费者模式的更多相关文章
- Java多线程—阻塞队列和生产者-消费者模式
阻塞队列支持生产者-消费者这种设计模式.该模式将“找出需要完成的工作”与“执行工作”这两个过程分离开来,并把工作项放入一个“待完成“列表中以便在随后处理,而不是找出后立即处理.生产者-消费者模式能简化 ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- Java 多线程学习笔记:生产者消费者问题
前言:最近在学习Java多线程,看到ImportNew网上有网友翻译的一篇文章<阻塞队列实现生产者消费者模式>.在文中,使用的是Java的concurrent包中的阻塞队列来实现.在看完后 ...
- Java多线程之并发协作生产者消费者设计模式
两个线程一个生产者个一个消费者 需求情景 两个线程,一个负责生产,一个负责消费,生产者生产一个,消费者消费一个 涉及问题 同步问题:如何保证同一资源被多个线程并发访问时的完整性.常用的同步方法是采用标 ...
- java多线程系列13 设计模式 Future 模式
Future 模式 类似于ajax请求 页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...
- Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法
本例定义了4个类,这里说一下,方便下面讲解.分别是Product(产品),Producer(生产者),Consumer(消费者), Test(测试类). 多线程之间通信与共享数据只要引用同一内存区域就 ...
- java多线程系列14 设计模式 Master-Worker
Master-Worker模式是常用的并行设计模式,可以将大任务划分为小任务,是一种分而治之的设计理念. 系统由两个角色组成,Master和Worker,Master负责接收和分配任务,Worker负 ...
- java多线程系列 目录
Java多线程系列1 线程创建以及状态切换 Java多线程系列2 线程常见方法介绍 Java多线程系列3 synchronized 关键词 Java多线程系列4 线程交互(wait和 ...
- 使用Lock锁生产者消费者模式
package com.java.concurrent; import java.util.concurrent.locks.Condition; import java.util.concurren ...
随机推荐
- 黄聪:解决Bootstrap模态框(modal)弹出后页面跑到顶部的办法
bootstrap 3.1.1 版本解决方案: body.modal-open { position: absolute !important; }
- percona-toolki安装冲突(my.cnf Percona-Server-shared与mysql-community-server)
最近在安装percona-toolkit工具包时,提示在my.cnf文件中, Percona-Server-shared与mysql-community-server冲突.起初还以为是一定需安装Per ...
- centos7 安装percona-toolkit工具包的安装和使用
一.检查和安装与Perl相关的模块 PT工具是使用Perl语言编写和执行的,所以需要系统中有Perl环境. 依赖包检查命令为: rpm -qa perl-DBI perl-DBD-MySQL perl ...
- Activiti图表bpmn对应的xml文件
当我们绘制了一个bpmn图表,实质是创建了一个xml文件, 右键bpmn文件open with xml edit <?xml version="1.0" encodin ...
- Numpy学习笔记(一)
(1)NumPy的核心对象 ndarray 用于表示N 维数组类型.它描述相同类型的元素集合. 可以使用基于零的索引访问集合中的项目. (2)Ndarray的创建 可以使用numpy.array() ...
- centos 全局环境变量设置
CentOS的环境变量配置文件体系是一个层级体系,这与其他多用户应用系统配置文件是类似的,有全局的,有用户的,有shell的,另外不同层级有时类似继承关系.下面以PATH变量为例. 1.修改/etc/ ...
- Python有趣时刻,这些代码让你大呼"卧槽,怎么会这样"
分享一个实用问题,用python读取Excel并保存字典,如何做? 下面是该同学问题截图和代码 image.png 代码截图是下面这样的 image.png 不知道大家第一眼看了这个代码,什么感受?我 ...
- Python 内置os模块的简单实用
获取路径&目录添加文件 在自动化测试的过程,考虑到工程文件的移动或者在其他人的工作环境中运行,所以我们的路径要灵活,不能把路径写死. 推荐使用Python的内置模块OS 参照图 import ...
- random的常用方式
Python中的random模块用于生成随机数 1.random.random() #用于生成一个0~1的随机浮点数:0<=n<1.0 >>> import random ...
- 协程,greenlet,gevent
""" 协程 """ ''' 协程: 类似于一个可以暂停的函数,可以多次传入数据,可以多次返回数据 协程是可交互的 耗资源大小:进程 --& ...