用Java写一个生产者-消费者队列
生产者消费者的模型作用
- 通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用。
- 解耦,这是生产者消费者模型附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展
使用阻塞队列来实现
package yunche.test.producer; import java.util.Random;
import java.util.concurrent.BlockingQueue; /**
* @ClassName: Producer
* @Description: 生产者
* @author: yunche
* @date: 2018/08/26
*/
public class Producer implements Runnable
{ private final BlockingQueue<Integer> queue; public Producer(BlockingQueue q)
{
this.queue = q;
} @Override
public void run()
{
try
{
while(true)
{
//模拟耗时1s
Thread.sleep(1000);
queue.put(produce());
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} private int produce()
{
int n = new Random().nextInt(10000);
System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n);
return n;
}
} package yunche.test.producer; import java.util.concurrent.BlockingQueue; /**
* @ClassName: Consumer
* @Description: 消费者
* @author: yunche
* @date: 2018/08/26
*/
public class Consumer implements Runnable
{
private final BlockingQueue<Integer> queue; public Consumer(BlockingQueue q)
{
this.queue = q;
} @Override
public void run()
{
while (true)
{
try
{
//模拟耗时
Thread.sleep(2000);
consume(queue.take());
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} } private void consume(Integer n)
{
System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n);
}
} package yunche.test.producer; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /**
* @ClassName: Main
* @Description: 测试类
* @author: yunche
* @date: 2018/08/26
*/
public class Main
{
public static void main(String[] args)
{
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100);
Producer p = new Producer(queue);
Consumer c1 = new Consumer(queue);
Consumer c2 = new Consumer(queue); Thread producer = new Thread(p);
producer.setName("生产者线程");
Thread consumer1 = new Thread(c1);
consumer1.setName("消费者1");
Thread consumer2 = new Thread(c2);
consumer2.setName("消费者2"); producer.start();
consumer1.start();
consumer2.start(); }
}

使用wait-notify来实现
package yunche.test.producer; import java.util.LinkedList;
import java.util.Random; /**
* @ClassName: Producer
* @Description: 生产者
* @author: yunche
* @date: 2018/08/26
*/
public class Producer implements Runnable
{ private final LinkedList<Integer> list; /**
* 缓冲区大小
*/
private final int maxSize; public Producer(LinkedList list, int size)
{
this.list = list;
maxSize =size;
} @Override
public void run()
{
try
{
while(true)
{
//模拟耗时1s
Thread.sleep(1000);
synchronized (list)
{
if(list.size()==maxSize)
{
System.out.println("缓冲区已满,正在等待消费者消费..." + System.currentTimeMillis());
list.wait();
}
else
{
list.add(produce());
list.notifyAll();
}
} }
}
catch (InterruptedException e)
{
e.printStackTrace();
}
} private int produce()
{
int n = new Random().nextInt(10000);
System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n);
return n;
}
} package yunche.test.producer; import java.util.Date;
import java.util.LinkedList; /**
* @ClassName: Consumer
* @Description: 消费者
* @author: yunche
* @date: 2018/08/26
*/
public class Consumer implements Runnable
{
private final LinkedList<Integer> list; public Consumer(LinkedList list)
{
this.list = list;
} @Override
public void run()
{
while (true)
{
try
{
synchronized(list)
{
//模拟耗时
Thread.sleep(1000);
if(list.isEmpty())
{
System.out.println("缓冲区已空,正在等待生产者生产..." + System.currentTimeMillis() + Thread.currentThread().getName());
list.wait();
}
else
{
consume(list.poll());
list.notifyAll();
}
} }
catch (InterruptedException e)
{
e.printStackTrace();
}
} } private void consume(Integer n)
{
System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n);
}
} package yunche.test.producer; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; /**
* @ClassName: Main
* @Description: 测试类
* @author: yunche
* @date: 2018/08/26
*/
public class Main
{
public static void main(String[] args)
{
LinkedList<Integer> list = new LinkedList<>();
Producer p = new Producer(list, 10);
Consumer c1 = new Consumer(list);
Consumer c2 = new Consumer(list); Thread producer = new Thread(p);
producer.setName("生产者线程");
Thread consumer1 = new Thread(c1);
consumer1.setName("消费者1");
Thread consumer2 = new Thread(c2);
consumer2.setName("消费者2"); producer.start();
consumer1.start();
consumer2.start(); }
}

参考资料
用Java写一个生产者-消费者队列的更多相关文章
- kafka集群搭建和使用Java写kafka生产者消费者
1 kafka集群搭建 1.zookeeper集群 搭建在110, 111,112 2.kafka使用3个节点110, 111,112 修改配置文件config/server.properties ...
- java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-【费元星Q9715234】
java+反射+多线程+生产者消费者模式+读取xml(SAX)入数据库mysql-[费元星Q9715234] 说明如下,不懂的问题直接我[费元星Q9715234] 1.反射的意义在于不将xml tag ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- java多线程模拟生产者消费者问题,公司面试常常问的题。。。
package com.cn.test3; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer消费者,Product产品 // ...
- Java并发之:生产者消费者问题
生产者消费者问题是Java并发中的常见问题之一,在实现时,一般可以考虑使用juc包下的BlockingQueue接口,至于具体使用哪个类,则就需要根据具体的使用场景具体分析了.本文主要实现一个生产者消 ...
- java多线程解决生产者消费者问题
import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class ...
- Java多线程同步——生产者消费者问题
这是马士兵老师的Java视频教程里的一个生产者消费者问题的模型 public class ProduceConsumer{ public static void main(String[] args) ...
- java模拟实现生产者---消费者问题
本文章为小编原创,请尊重文章的原创性,转载请注意写明转载来源:http://blog.csdn.net/u012116457 已知技术參数: 生产者消费者问题,描写叙述一组生产者向一组消费者提供产品/ ...
- C# 实现生产者消费者队列
开发过程中经常会碰到这样的场景:需要从一个地方获取一些数据,然后处理数据并将其保存在数据库中. 1 2 3 4 5 6 7 8 9 10 private void FetchData() {} pri ...
随机推荐
- Mac OS X 10.10下Versions crash的问题
升级完系统.Versions由于兼容性到问题,各种闪退,网上搜索了一下.知乎到一个帖子提到了暂时解决的方法,例如以下: Blackpixel 正在研究此崩溃的修复方案.暂时解决方式例如以下: 在文本编 ...
- [办公自动化]凭证纸打印 IE 默认设置
财务人员需要打印凭证纸,系统windows7,打印机HP P1106 在自定义纸张类型中设置凭证纸. 属性,打印首选项,“纸张和质量”选卡处,单击自定义(需要管理员权限) 输入“PZ” 宽148 高2 ...
- P1198 [JSOI2008]最大数(线段树)
P1198 [JSOI2008]最大数(线段树) 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值 ...
- Codeforces Round #369 (Div. 2) 套题
A:模拟水题不说 #include <iostream> #include <string.h> #include <algorithm> #include < ...
- lucene .doc文件格式解析——见图
摘自:http://forfuture1978.iteye.com/blog/546841 4.2.2. 文档号及词频(frq)信息 文档号及词频文件里面保存的是倒排表,是以跳跃表形式存在的. 此文件 ...
- 【JSOI 2008】 最小生成树计数
[题目链接] 点击打开链接 [算法] 笔者做这题参考了这篇博客 : https://blog.sengxian.com/solutions/bzoj-1016 推荐阅读 首先,我们需要知道三个定理 : ...
- POJ1808 平方(二次)同余方程
POJ1808 给定一个方程 x*x==a(mod p) 其中p为质数 判断是否有解 程序中 MOD_sqr()返回整数解 无解返回-1 数学证明略 #include<iostream> ...
- .NET 导入导出Excel
第一种方式:OleDb 需要安装office,且读数据慢,而且有数据格式的Cell读出数据不正确等问题.放弃. 第二种方式:NPOI开源库 使用NPOI导入导出Excel应该是.NET开发很常用的手段 ...
- CSS3 动画 @keyframes
通过 CSS3,我们能够创建动画,这可以在许多网页中取代动画图片.Flash 以及 JavaScript. 如下动画,常用于手机端,提示用户往下拖动的渐隐渐出效果. Demo 关键CSS代码 1. 给 ...
- Django day35 redis连接池,redis-list操作,django中使用redis,支付宝支付
一:redis连接池, 二:redis-list操作, 三:django中使用redis, 四:支付宝支付