http://tonl.iteye.com/blog/1936391

使用Java的BlockingQueue实现生产者-消费者

BlockingQueue也是java.util.concurrent下的主要用来控制线程同步的工具。

BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。

2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。

3、PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序。

4、SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。

LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。

生产者消费者的示例代码:

生产者:

  1. import java.util.concurrent.BlockingQueue;
  2. public class Producer implements Runnable {
  3. BlockingQueue<String> queue;
  4. public Producer(BlockingQueue<String> queue) {
  5. this.queue = queue;
  6. }
  7. @Override
  8. public void run() {
  9. try {
  10. String temp = "A Product, 生产线程:"
  11. + Thread.currentThread().getName();
  12. System.out.println("I have made a product:"
  13. + Thread.currentThread().getName());
  14. queue.put(temp);//如果队列是满的话,会阻塞当前线程
  15. } catch (InterruptedException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. }

消费者:

  1. import java.util.concurrent.BlockingQueue;
  2. public class Consumer implements Runnable{
  3. BlockingQueue<String> queue;
  4. public Consumer(BlockingQueue<String> queue){
  5. this.queue = queue;
  6. }
  7. @Override
  8. public void run() {
  9. try {
  10. String temp = queue.take();//如果队列为空,会阻塞当前线程
  11. System.out.println(temp);
  12. } catch (InterruptedException e) {
  13. e.printStackTrace();
  14. }
  15. }
  16. }

测试类:

  1. import java.util.concurrent.ArrayBlockingQueue;
  2. import java.util.concurrent.BlockingQueue;
  3. import java.util.concurrent.LinkedBlockingQueue;
  4. public class Test3 {
  5. public static void main(String[] args) {
  6. BlockingQueue<String> queue = new LinkedBlockingQueue<String>(2);
  7. // BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
  8. //不设置的话,LinkedBlockingQueue默认大小为Integer.MAX_VALUE
  9. // BlockingQueue<String> queue = new ArrayBlockingQueue<String>(2);
  10. Consumer consumer = new Consumer(queue);
  11. Producer producer = new Producer(queue);
  12. for (int i = 0; i < 5; i++) {
  13. new Thread(producer, "Producer" + (i + 1)).start();
  14. new Thread(consumer, "Consumer" + (i + 1)).start();
  15. }
  16. }
  17. }

打印结果:

  1. I have made a product:Producer1
  2. I have made a product:Producer2
  3. A Product, 生产线程:Producer1
  4. A Product, 生产线程:Producer2
  5. I have made a product:Producer3
  6. A Product, 生产线程:Producer3
  7. I have made a product:Producer5
  8. I have made a product:Producer4
  9. A Product, 生产线程:Producer5
  10. A Product, 生产线程:Producer4

由于队列的大小限定成了2,所以最多只有两个产品被加入到队列当中,而且消费者取到产品的顺序也是按照生产的先后顺序,原因就是LinkedBlockingQueue和ArrayBlockingQueue都是按照FIFO的顺序存取元素的。

使用Java的BlockingQueue实现生产者-消费者的更多相关文章

  1. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  2. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  3. Java多线程(十):BlockingQueue实现生产者消费者模型

    BlockingQueue BlockingQueue.解决了多线程中,如何高效安全"传输"数据的问题.程序员无需关心什么时候阻塞线程,什么时候唤醒线程,该唤醒哪个线程. 方法介绍 ...

  4. 使用BlockingQueue的生产者消费者模式

    BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...

  5. Queue和BlockingQueue的使用以及使用BlockingQueue实现生产者-消费者

    Java提供了两种新的容器类型:Queue和BlockingQueue. Queue用于保存一组等待处理的元素.它提供了几种实现,包括:ConcurrentLinkedQueue,这是一个先进先出的并 ...

  6. Java多线程-并发协作(生产者消费者模型)

    对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一样,Hello World!都是最经典的例子. 实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓 ...

  7. JAVA多线程经典问题 -- 生产者 消费者

    工作2年多来一直也没有计划写自己的技术博客,最近辞职在家翻看<thingking in JAVA>,偶尔看到了生产者与消费者的一个经典的多线程同步问题.本人在工作中很少使用到多线程以及高并 ...

  8. Java 管程解决生产者消费者问题

    同样是实验存档.//.. 依然以生产者消费者问题作为背景. 管程(=“资源管理程序”)将资源和对资源的操作封装起来,资源使用者通过接口操作资源就 ok,不用去考虑进程同步的问题. 管程: packag ...

  9. java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现

    java多线程15 :wait()和notify() 的生产者/消费者模式 在这一章已经实现了  wait/notify 生产消费模型 利用await()/signal()实现生产者和消费者模型 一样 ...

随机推荐

  1. use 2 stacks to simulate a queue

    class Stack{ private: ; ]; public: void push(int n); int pop(); int peek(); int size(); }; void Stac ...

  2. 让ECSHOP模板支持转smarty时间戳

    找到includes/cls_template.php 在大约640行,加入: case 'time': $p = 'date("Y-m-d H:i:s",' . $p . ')' ...

  3. Jenkins - 持续集成环境搭建【转】

    1. Jenkins 概述 Jenkins是一个开源的持续集成工具.持续集成主要功能是进行自动化的构建.自动化构建包括自动编译.发布和测试,从而尽快地发现集成错误,让团队能够更快的开发内聚的软件. 2 ...

  4. js几种基本数据类型及之间转换与java的不同、js数组一些常见操作

    js的三大组成部分及各自作用: 1.ECMAScript:规范了js的基本语法和功能 2.DOM:js操作页面元素的API 3.BOM:js操作浏览器部分功能的API 如果通过<script s ...

  5. USB LPT 端口映射

    如何设置端口映射(以将LPT1端口映射到共享名为CutePDFW的虚拟打印机上为例),命令如下: NET USE LPT1: \\wcjxixi-d022704\CutePDFW /Persisten ...

  6. HDU3371--Connect the Cities(最小生成树)

    Problem Description In 2100, since the sea level rise, most of the cities disappear. Though some sur ...

  7. sql 判断表是否存在,判断列是否存在

    判断表是否存在: 语法: SELECT * FROM dbo.SysObjects where id = object_id(N'表名') 例子: SELECT * FROM dbo.SysObjec ...

  8. Linux系统采用netstat命令查看DDOS攻击的方法

    Linux系统采用netstat命令查看DDOS攻击的方法 来源:互联网 作者:佚名 时间:07-05 15:10:21 [大 中 小] 这篇文章主要为大家介绍了Linux系统采用netstat命令查 ...

  9. js第一天 inner html value

    <html> <head> <meta charset="utf-8" /> <title></title> <s ...

  10. apache: 503

    Any connection over Max, will get a 503 Service Temporarily Unavailable. 503出现的场景:压测url时,发现大量的503错误. ...