用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 ...
随机推荐
- 安装ubuntu后启动黑屏
我是在windows7上的一个空暇盘上安装ubuntu 14.安装后重新启动没有ubuntu的启动项,然后用easybcd生成启动项,重新启动发现果然有,可是选择之后黑屏. 百度半天无果.后来无意发现 ...
- 【bzoj4597】 [Shoi2016]随机序列
可以发现加减号之间可以互相抵消. 真正加到答案里的只有一些前缀积. 记s[i]为a[1]*a[2]*a[3]...*a[i].那s[i]在答案中出现的次数就是2*3^(n-i-1); 修改一个数只会对 ...
- HDU 5832A water problem
大数 判断整除 /* *********************************************** Author :guanjun Created Time :2016/8/14 1 ...
- 关于Web API中使用ajax发送请求方式的问题
参见以下文章 http://www.west-wind.com/weblog/posts/2012/May/08/Passing-multiple-POST-parameters-to-Web-API ...
- CMake使用总结
总结CMake的常用命令,并介绍有用的CMake资源. CMake意为cross-platform make,可用于管理c/c++工程.CMake解析配置文件CMakeLists.txt生成Makef ...
- 几个SQL小知识(转)
原文地址:http://www.cnblogs.com/wuguanglei/p/4205976.html 写在前面的话:之前做的一个项目,数据库及系统整体构架设计完成之后,和弟兄们经过一段时间的编码 ...
- Akka源码分析-Cluster-Sharding
个人觉得akka提供的cluster工具中,sharding是最吸引人的.当我们需要把actor分布在不同的节点上时,Cluster sharding非常有用.我们可以使用actor的逻辑标识符与ac ...
- VUE中全局变量的定义和使用
目录 VUE中全局变量的定义和使用 1.工作中遇到的两类问题 1.1 状态值(标志) 1.2 传递字段 2.解决方法 2.1 VUEX 2.2 使用全局变量法管理状态与字段值 3.具体实现 3.1创建 ...
- Get 和 Post 使用篇(1)
1.Post 请求发送方式 实例: const string sResponseEncoding = "gb2312"; //测试文本信息 string postText = &q ...
- MSSQLServer知识点总结:DDL(create,alter,drop,declare)-未完整
一.开发环境 Window10 二.开发工具 SQLServer2012 三.数据库的操作 1.创建 (1)方式一:使用默认的配置信息 create database T_mydb2 (2)方式二:自 ...