通过BlockingQueue实现生产者和消费者问题
来源:互联网 发布:淘宝买家退货率高 编辑:程序博客网 时间:2024/05/24 05:50
摘自http://wsmajunfeng.iteye.com/blog/1629354
import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeUnit;import java.util.concurrent.atomic.AtomicInteger;public class Producer implements Runnable { private volatile boolean isRunning = true; private BlockingQueue<String> queue; public static AtomicInteger count = new AtomicInteger(); private static final int DEFAULT_RANGE_FOR_SLEEP = 1000; public Producer(BlockingQueue<String> queue) { this.queue = queue; } @Override public void run() { String data = null; Random random = new Random(); System.out.println("启动生产者线程!"); try { while (isRunning) { System.out.println("正在生产数据"); Thread.sleep(random.nextInt(DEFAULT_RANGE_FOR_SLEEP)); data = "data:" + count.incrementAndGet(); if (!queue.offer(data, 2, TimeUnit.SECONDS)) System.out.println("放入数据失败"); } } catch (Exception e) { e.printStackTrace(); Thread.currentThread().interrupt(); } finally { System.out.println("退出生产者线程!"); } } public void stop() { isRunning = false; }}
import java.util.Random;import java.util.concurrent.BlockingQueue;import java.util.concurrent.TimeUnit;public class Consumer implements Runnable { private BlockingQueue<String> queue; private static final int DEFAULT_RANGE_FOR_SLEEP = 1000; public Consumer(BlockingQueue<String> queue) { this.queue = queue; } @Override public void run() { System.out.println("启动消费者线程!"); Random random = new Random(); boolean isRunning = true; try { while (isRunning) { System.out.println("正在从队列获取数据"); String data = queue.poll(2, TimeUnit.SECONDS); if (data != null) { System.out.println("拿到数据:" + data); System.out.println("正在消费数据"); System.out.println("队列长度:"+queue.size()); Thread.sleep(random.nextInt(DEFAULT_RANGE_FOR_SLEEP)); } else { // 超过2s还没数据,认为所有生产线程都已经退出,自动退出消费线程。 isRunning = false; } } } catch (Exception e) { e.printStackTrace(); Thread.currentThread().interrupt(); } finally { System.out.println("退出消费者线程!"); System.out.println("总生产数:" + Producer.count); } }}
import java.util.concurrent.BlockingQueue;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.LinkedBlockingQueue;public class BlockingQueueTest { public static void main(String[] args) throws InterruptedException { BlockingQueue<String> queue = new LinkedBlockingQueue<String>(10); Producer producer1 = new Producer(queue); Producer producer2 = new Producer(queue); Producer producer3 = new Producer(queue); Consumer consumer = new Consumer(queue); ExecutorService service = Executors.newCachedThreadPool(); service.execute(producer1); service.execute(producer2); service.execute(producer3); service.execute(consumer); Thread.sleep(10 * 1000); producer1.stop(); producer2.stop(); producer3.stop(); Thread.sleep(2000); service.shutdown(); }}
ArrayBlockingQueue与LinkedBlockingQueue
ArrayBlockingQueue:
基于数组的阻塞队列实现,在ArrayBlockingQueue内部,维护了一个定长数组,以便缓存队列中的数据对象,这是一个常用的阻塞队列,除了一个定长数组外,ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue。
LinkedBlockingQueue:
基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。而LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。
阅读全文
0 0
- 通过BlockingQueue实现生产者和消费者问题
- 生产者和消费者问题-使用BlockingQueue来实现
- 使用BlockingQueue实现生产者和消费者模型
- 使用BlockingQueue实现生产者和消费者模式
- 生产者,消费者的BlockingQueue实现
- 利用BlockingQueue实现生产者消费者
- BlockingQueue实现生产者、消费者模式
- BlockingQueue实现生产者消费者模式
- 通过生产者消费者问题比较信号量和信号【Java实现】
- Java多线程-工具篇-BlockingQueue(实现生产者和消费者模式)
- Java利用BlockingQueue实现生产者和消费者模式
- 基于BlockingQueue的生产者消费者模式实现
- Java实现生产者消费者模型:多线程+BlockingQueue
- 使用BlockingQueue实现生产者消费者模式
- 使用Java的BlockingQueue实现生产者-消费者
- Java使用BlockingQueue实现生产者消费者模式
- 使用Java的BlockingQueue实现生产者-消费者
- 使用Java的BlockingQueue实现生产者-消费者
- tabbar视图控制器之间的切换
- MFC禁止对话框的拖动
- Android事件传递
- vim中Ctrl+t和Ctrl+o快捷键的区别
- mysql日志文件恢复数据
- 通过BlockingQueue实现生产者和消费者问题
- 一、GIT创建版本库基本命令
- Linux Driver教程PPT
- SAS统计分析学习笔记(八)——T检验和非参数比较
- C++ map基本操作实例
- UIWebView 追加UA信息
- 编译Python源代码
- opencv鼠标经过读取坐标以及划动画框
- #1052最大报销额