用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 ...
随机推荐
- VC++ 模拟"CLICK事件"关闭指定窗体
今天改动一个工具时遇到一个有意思的问题,打开某个窗体时弹出一些不相关的窗体.须要用户自己去手动点击后才干继续.保证不了自己主动处理,如今解说决方案记录一下,例如以下 主要使用windows提供的Fin ...
- [翻译]NUnit--Getting Started(二)
Getting Started with NUnit 如果你打算开始学习,到下载页面选择一个NUnit版本.安装页面包含了安装说明. 开始NUnit阅读Quick Start页面.验证了一个C#银行应 ...
- 洛谷P1719 最大加权矩形
题目描述 为了更好的备战NOIP2013,电脑组的几个女孩子LYQ,ZSC,ZHQ认为,我们不光需要机房,我们还需要运动,于是就决定找校长申请一块电脑组的课余运动场地,听说她们都是电脑组的高手,校长没 ...
- codeforces AIM Tech Round 4 div 2
A:开个桶统计一下,但是不要忘记k和0比较大小 #include<bits/stdc++.h> using namespace std; ]; ]; int main() { int k; ...
- RabbitMQ学习之Work Queues(2)
目录: 轮询调度(Round-robin dispatching):即依次分配分配任务给worker. 消息答复(Message acknowledgement):在consumer处理完之后,进行消 ...
- mongodb海量数据CRUD优化
1. 批量保存优化 避免一条一条查询,采用bulkWrite, 基于ReplaceOneModel,启用upsert: public void batchSave(List<?> spoT ...
- 数据结构之单链表(C实现)
list.h #ifndef LIST_H #define LIST_H #include <iostream> #include <stdio.h> #include < ...
- [C和指针] 4-语句、5-操作符和表达式
第4章 语句 4.1 表达式语句 C并不存在专门的"赋值语句",赋值就是一种操作,就像加法和减法一样,所以赋值就在表达式内进行. 你只要在表达式后面加上一个分号,就可以把表达式转变 ...
- EditText(8)EditText中drawableRight图片的点击事件
参考: http://stackoverflow.com/questions/3554377/handling-click-events-on-a-drawable-within-an-edittex ...
- 转 DOS(CMD)下批处理换行问题/命令行参数换行 arg ms-dos
DOS(CMD)下批处理换行问题本人经常写一些DOS批处理文件,由于批处理中命令的参考较多且长,写在一行太不容易分辨,所以总想找个办法把一条命令分行来写,今天终于试成功两种方法.一.在CMD下,可以用 ...