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 ...
随机推荐
- MYSQL存储过程实现用户登录
MYSQL存储过程实现用户登录 CREATE DEFINER=`root`@`%` PROCEDURE `uc_session_login`( ), ) ) LANGUAGE SQL NOT DETE ...
- ThinkPHP5.*版本发布安全更新
2018 年 12 月 9 日 发布 本次版本更新主要涉及一个安全更新,由于框架对控制器名没有进行足够的检测会导致在没有开启强制路由的情况下可能的getshell漏洞,受影响的版本包括5.0和5.1版 ...
- c# word操作篇,解决字符串长度超过255就不能替换的问题
本文使用的是Microsoft.Office.Interop.Word组件,必须在系统安装了office相关组件的条件下进行,在com里面找到Microsoft Word 16.0 Object L ...
- Backbone 学习总结
1.Backbone描述 官网描述:(1)Provides client-side app structure (2)Models to repents data (3)View to hook up ...
- C++中宽字符类型(wchar_t)的编码
转载自: http://www.ituring.com.cn/article/111027 问题的起因是和一个朋友讨论不同编码的转换问题,说到了wchar_t的类型,朋友的看法是,wchar_t的编码 ...
- 【阿里云服务器】外网无法访问tomcat下部署的项目
问题提出:在ESC实例上部署了jdk和tomcat(略,上云了,上云了),启动tomct后,内网可以访问8080端口,外网无法访问8080. 系统环境:winsdow 2008 企业版 解决方案: 在 ...
- JAVA中循环删除list中元素的方法总结(同上篇)
印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...
- github 添加wiki
亲们支持我的新博客哦==>地址(以后更新会尽量在新博客更新,欢迎大家访问加入我的后宫w) ) 平时都是写readMe和docs的,一直眼瞎没有注意到有wiki这个功能 随便找一个写了wiki的看 ...
- Java序列化机制原理
Java序列化就是将一个对象转化为一个二进制表示的字节数组,通过保存或则转移这些二进制数组达到持久化的目的.要实现序列化,需要实现java.io.Serializable接口.反序列化是和序列化相 ...
- list按照某个元素进行排序
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...