java 多线程并发系列之 生产者消费者模式的两种实现
来源:互联网 发布:全自动打码软件 编辑:程序博客网 时间:2024/05/14 15:22
生产者消费者模式是并发、多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据。
真实世界中的生产者消费者模式
生产者和消费者模式在生活当中随处可见,它描述的是协调与协作的关系。比如一个人正在准备食物(生产者),而另一个人正在吃(消费者),他们使用一个共用的桌子用于放置盘子和取走盘子,生产者准备食物,如果桌子上已经满了就等待,消费者(那个吃的)等待如果桌子空了的话。这里桌子就是一个共享的对象。
我们看这样一个例子:
生产者: 往一个公共的盒子里面放苹果
消费者:从公共的盒子里面取苹果
盒子:盒子的容量不能超过5
下面我们用两者方法分别实现这样一个场景。
方法一: wait() 和 notify() 通信方法实现
看盒子代码
public class PublicBox {
private int apple = 0;
public synchronized void increace() {
while (apple ==5) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
apple++;
System. out .println("生成苹果成功!" );
notify();
}
public synchronized void decreace() {
while (apple ==0) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
apple--;
System. out.println( "消费苹果成功!" );
notify();
}
public static void main(String []args)
{
PublicBox box= new PublicBox();
Consumer con= new Consumer(box);
Producer pro= new Producer(box);
Thread t1= new Thread(con);
Thread t2= new Thread(pro);
t1.start();
t2.start();
}
}
生产者代码(定义十次):
public class Producer implements Runnable {
private PublicBox box;
public Producer(PublicBox box) {
this .box = box;
}
@Override
public void run() {
for( int i=0;i<10;i++)
{
try {
System. out .println("pro i:" +i);
Thread. sleep(30);
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
box.increace();
}
}
}
消费者代码(同样十次):
public class Consumer implements Runnable {
private PublicBox box;
public Consumer(PublicBox box) {
this .box = box;
}
@Override
public void run() {
for( int i=0;i<10;i++)
{
try {
System. out .println("Con: i " +i);
Thread. sleep(3000); // 这里设置跟上面30不同是为了 盒子中的苹果能够增加,不会生产一个马上被消费
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
box.decreace();
}
}
}
输出如下:
pro i:0
Con: i 0
生成苹果成功!
pro i:1
生成苹果成功!
pro i:2
生成苹果成功!
pro i:3
生成苹果成功!
pro i:4
生成苹果成功!
pro i:5
消费苹果成功!
Con: i 1
生成苹果成功!
pro i:6
消费苹果成功!
Con: i 2
生成苹果成功!
pro i:7
消费苹果成功!
生成苹果成功!
pro i:8
Con: i 3
消费苹果成功!
生成苹果成功!
pro i:9
Con: i 4
消费苹果成功!
生成苹果成功!
Con: i 5
消费苹果成功!
Con: i 6
消费苹果成功!
Con: i 7
消费苹果成功!
Con: i 8
消费苹果成功!
Con: i 9
消费苹果成功!
方法二:采用阻塞队列实现生产者消费者模式
盒子代码:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class PublicBoxQueue {
public static void main(String []args)
{
BlockingQueue publicBoxQueue= new LinkedBlockingQueue(5); //定义了一个大小为5的盒子
Thread pro= new Thread(new ProducerQueue(publicBoxQueue));
Thread con= new Thread(new ConsumerQueue(publicBoxQueue));
pro.start();
con.start();
}
}
生产者:
package dsd;
import java.util.concurrent.BlockingQueue;
public class ProducerQueue implements Runnable {
private final BlockingQueue proQueue;
public ProducerQueue(BlockingQueue proQueue)
{
this .proQueue =proQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i=0;i<10;i++)
{
try {
System. out .println("生产者生产的苹果编号为 : " +i); //放入十个苹果编号 为1到10
proQueue .put(i);
/*Thread.sleep(3000);*/
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
消费者:
package dsd;
import java.util.concurrent.BlockingQueue;
public class ConsumerQueue implements Runnable {
private final BlockingQueue conQueue;
public ConsumerQueue(BlockingQueue conQueue)
{
this .conQueue =conQueue;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i=0;i<10;i++)
{
try {
System. out .println("消费者消费的苹果编号为 :" +conQueue .take());
Thread. sleep(3000); //在这里sleep是为了看的更加清楚些
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
结果如下:
生产者生产的苹果编号为 : 0
生产者生产的苹果编号为 : 1
消费者消费的苹果编号为 :0
生产者生产的苹果编号为 : 2
生产者生产的苹果编号为 : 3
生产者生产的苹果编号为 : 4
生产者生产的苹果编号为 : 5
生产者生产的苹果编号为 : 6
生产者生产的苹果编号为 : 7
消费者消费的苹果编号为 :1
消费者消费的苹果编号为 :2
生产者生产的苹果编号为 : 8
消费者消费的苹果编号为 :3
生产者生产的苹果编号为 : 9
消费者消费的苹果编号为 :4
消费者消费的苹果编号为 :5
消费者消费的苹果编号为 :6
消费者消费的苹果编号为 :7
消费者消费的苹果编号为 :8
消费者消费的苹果编号为 :9
生产者消费者模式的好处
它的确是一种实用的设计模式,常用于编写多线程或并发代码。下面是它的一些优点:
- 它简化的开发,你可以独立地或并发的编写消费者和生产者,它仅仅只需知道共享对象是谁
- 生产者不需要知道谁是消费者或者有多少消费者,对消费者来说也是一样
- 生产者和消费者可以以不同的速度执行
- 分离的消费者和生产者在功能上能写出更简洁、可读、易维护的代码
阅读全文
0 0
- java 多线程并发系列之 生产者消费者模式的两种实现
- java 多线程并发系列之 生产者消费者模式的两种实现
- Java多线程之并发协作生产者消费者设计模式
- Java多线程之并发协作生产者消费者设计模式
- Java多线程之并发协作生产者消费者设计模式
- Java多线程之并发协作生产者消费者设计模式
- Java多线程之并发协作生产者消费者设计模式
- Java并发编程系列之十三:生产者-消费者模式
- java多线程实现生产者消费者模式
- Java多线程实现消费者/生产者模式
- Java多线程实现生产者消费者模式
- java 多线程实现生产者消费者模式
- Java多线程实现简单生产者消费者模式
- java多线程之消费者生产者模式
- Java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- java多线程之消费者生产者模式
- Java内部类(成员内部类、静态内部类、局部内部类、匿名内部类)小结
- dubbox
- 计蒜客 Our Journey of Dalian Ends(17新疆网赛) 费用流(思维建图)
- gogland调试服务器网站遇到问题
- STM32/8单片机相关
- java 多线程并发系列之 生产者消费者模式的两种实现
- hdu 1430 bfs + 打表 + 康拓展开
- 利用for循环输出乘法口诀表
- OSI七层模型与TCP/IP五层模型简介
- 萌新的初修之路
- Nginx学习: 负载均衡session会话保持方法
- 机器学习之分类器性能指标之ROC曲线、AUC值
- 2017秋季排球联赛
- java连接mysql数据库的详细步骤