生产者和消费者三种实现
来源:互联网 发布:网络信号大师 编辑:程序博客网 时间:2024/05/18 09:56
1、syncronized+wait+notify
package com.rrfare.producerconsumer;import java.util.LinkedList;import java.util.Queue;import java.util.Random;public class OrderManager { // 容器最大值 private static final int MAX_COUNT = 5; // 容器(这里不使用BlockingQueue,而是使用线程不安全的LinkedList,并结合syncronized保证线程安全) private Queue<Order> orderQueue = new LinkedList<Order>(); private Random random = new Random(); public static void main(String[] args) { OrderManager shareObj = new OrderManager(); Thread produceThread = new Thread(new ProducerThread(shareObj)); Thread produceThread2 = new Thread(new ProducerThread(shareObj)); produceThread.start(); produceThread2.start(); Thread consumerThread = new Thread(new ConsumeThread(shareObj)); Thread consumerThread2 = new Thread(new ConsumeThread(shareObj)); consumerThread.start(); consumerThread2.start(); } public synchronized void addOrder(){ while(orderQueue.size() >= MAX_COUNT){ try { System.out.println(Thread.currentThread().getName() + "队列已满,待会再生产"); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } int i = random.nextInt(1000); Order tempOrder = new Order(i,"order"+i); orderQueue.offer(tempOrder); // use prefer to add System.out.println(Thread.currentThread().getName() + "--produce order--" + tempOrder); notifyAll(); } public synchronized void takeOrder(){ while(orderQueue.size() < 1){ try { System.out.println(Thread.currentThread().getName() + "队列已空,等待生产"); wait(); } catch (InterruptedException e) { e.printStackTrace(); } } Order tempOrder = orderQueue.poll(); // use prefer to remove System.out.println(Thread.currentThread().getName() + "--consume order--" + tempOrder); notifyAll(); }}class ProducerThread implements Runnable { private OrderManager orderManager; public ProducerThread(OrderManager orderManager) { this.orderManager = orderManager; } @Override public void run() { while(true){ orderManager.addOrder(); } }}class ConsumeThread implements Runnable { private OrderManager orderManager; public ConsumeThread(OrderManager orderManager) { this.orderManager = orderManager; } @Override public void run() { while(true){ orderManager.takeOrder(); } } }
2、BlockingQueue
public class UseBlockQueue { /** * 队列元素数量达到指定容量时会阻塞生产者线程,消费者消费数据时,生产者线程又被唤醒 * LinkedBlockingQueue实现中生产者和消费者使用了不同的锁,消费者和生产者可以并发处理队列中数据,因此可以用于高并发应用中 * 注意:默认构造时会创建一个无限大队列,这样如果生产者速度一旦大于消费者,就会导致资源慢慢耗尽,因此构造时最好显式指定容量 */ private static BlockingQueue<Order> orderQueue = new LinkedBlockingQueue<Order>(10); // BlockingQueue内部实现了同步细节,直接使用很方便 /** * 内部维护一个定长数组 * ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,导致生产者和消费者无法并行操作数据 * ArrayBlockingQueue和LinkedBlockingQueue重要区别在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例, * 而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,对于GC的影响存在一定的区别 */ private static BlockingQueue<Order> orderQueue2 = new ArrayBlockingQueue<Order>(10); public static void main(String[] args) { Thread produceThread = new Thread(new ProducerThread(orderQueue)); Thread consumerThread1 = new Thread(new ConsumerThread(orderQueue)); Thread consumerThread2 = new Thread(new ConsumerThread(orderQueue)); produceThread.start(); consumerThread1.start(); consumerThread2.start(); }}class ConsumerThread implements Runnable { private BlockingQueue<Order> order_Queue; public ConsumerThread(BlockingQueue<Order> orderQueue){ this.order_Queue = orderQueue; } @Override public void run() { while(true){ Order tempOrder = null; try { tempOrder = order_Queue.take(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--consume order--" + tempOrder); } }}class ProducerThread implements Runnable { private Random random = new Random(); private BlockingQueue<Order> order_Queue; public ProducerThread(BlockingQueue<Order> orderQueue){ this.order_Queue = orderQueue; } @Override public void run() { while(true){ int i = random.nextInt(1000); Order tempOrder = new Order(i,"order"+i);// order_Queue.add(tempOrder); // add和put的区别:前者在队列满之后如果继续添加会抛出异常;后者会进入阻塞状态等待消费者消费腾出空间后继续 try { order_Queue.put(tempOrder); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"--produce order--" + tempOrder); } }}
3、Redis List(Redis也支持发布订阅模式,同样可以实现生产者和消费者)
public class TestRedis { private static final String REDIS_ADDR = "127.0.0.1:6379:0"; private static final String REDIS_LIST_KEY = "myList"; private static final int MAX_COUNT = 200; public static void main(String[] args) { RedisListDao_C redisListDao = new RedisListDao_C(REDIS_ADDR); Thread consumerT = new Thread(new ConsumerThread(redisListDao, REDIS_LIST_KEY)); Thread producerT = new Thread(new ProducerThread(redisListDao, REDIS_LIST_KEY,MAX_COUNT)); producerT.start(); consumerT.start(); }}class ConsumerThread implements Runnable { RedisListDao_C redisDao; String redisListKey; public ConsumerThread(RedisListDao_C redisListDao,String redisListKey){ this.redisDao = redisListDao; this.redisListKey = redisListKey; } public void run() { while(true){ // 使用blpop,当没有订单可消费时,进入阻塞状态,超时参数设为 0 表示阻塞时间可以无限期延长(block indefinitely) // blpop传入参数示例:key1 key2 key3 timeout // blpop返回第一个不为空的列表记录,示例:key1 value1 List<String> value = redisDao.blpop(new String[]{redisListKey,"0"}); if(value == null) continue; System.out.println(Thread.currentThread().getName() + "--consume--" + value.get(1)); } }}class ProducerThread implements Runnable { RedisListDao_C redisDao; String redisListKey; int MAX_COUNT; Random random = new Random(); public ProducerThread(RedisListDao_C redisListDao,String redisListKey,int maxCount){ this.redisDao = redisListDao; this.redisListKey = redisListKey; MAX_COUNT = maxCount; } public void run() { while(true){ String tempValue = "Order"+random.nextInt(1000); redisDao.rpush(redisListKey,tempValue); System.out.println(Thread.currentThread().getName() + "--Produce--" + tempValue); // 达到阈值后暂停10秒钟再生产,注意:虽然一直在生产,很容易达到200阈值,但是也一直在消费(清除) if(redisDao.len(redisListKey) >= MAX_COUNT){ try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
4、MessageQueue
阅读全文
0 0
- 生产者和消费者三种实现
- java实现生产者消费者--三种方式
- Java 实现生产者和消费者
- 生产者和消费者Java实现
- ActivityMQ实现生产者和消费者
- 生产者和消费者线程实现
- java线程:三种方式实现生产者消费者问题_1
- java线程:三种方式实现生产者消费者问题_2
- java线程:三种方式实现生产者消费者问题_3
- 生产者消费者三种并发模式实现方法
- 三种方法实现生产者/消费者模型(Java)
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- C#多线程学习(三) 生产者和消费者
- 51Nod 1116 K进制下的大数
- maven 项目 Java Resources 文件报错解决
- 【二叉树】判断二叉树是否对称
- [数论] Codeforces 819D R #421 D.Mister B and Astronomers & 516E R #292 E. Drazil and His Happy Friends
- ubuntu 14.04 识别展讯手机
- 生产者和消费者三种实现
- Visual Studio 2015
- CSS块元素居中
- python之集合
- 工程应用另外一个工程
- 利用Github+Hexo轻松搭建个人博客
- 我录制的《Java之IO , BIO , NIO , AIO 知多少?》视频教程发布了
- QML ScrollView使用Rectangle没有下拉条解决方法
- 4关于管理和监控工具