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. docker network

    前言:前面的部分一直都是单机跑docker,但实际生产环境不可能只用一台来跑.肯定会用到多台,因为他们都是内部私有ip,那么多台主机之间的容器如何通信?这个是个很头疼的问题!目前主流几种方法如下: 1 ...

  2. c#实现输出本月的月历

    效果如图: 代码如下: namespace WebForm { public partial class WebForm1 : System.Web.UI.Page { protected void ...

  3. 2.Thread中的实例方法

    (转自:http://www.cnblogs.com/xrq730/p/4851233.html) Thread类中的方法调用方式: 1.this.XXX 这种调用方式表示的线程是:线程实例本身 2. ...

  4. Power oj2498/DP/递推

    power oj 2498 /递推 2498: 新年礼物 Time Limit: 1000 MS Memory Limit: 65536 KBTotal Submit: 12 Accepted: 3  ...

  5. gridControl 部分属性

    DEVexpress GridControl 属性设置 2013年11月22日 ⁄ 综合 ⁄ 共 18319字 ⁄ 字号 小 中 大 ⁄ 评论关闭 1. 如何解决单击记录整行选中的问题 View-&g ...

  6. android代码格式化方法小结

    转载:http://blog.csdn.net/androidzhaoxiaogang/article/details/7692526 Download the android-formatting. ...

  7. 解题的小问题(C++)

    1.判断一个数是否为整数  if(m==(int)m) 2.#include <bits/stdc++.h>using namespace std;int main(){    int n ...

  8. C#连接ACCESS的一个问题

    C# 连接ACCESS数据库有时候报 "Microsoft.Jet.Oledb.4.0"没有注册,其实,并不是真的没注册,可能是下面的原因 在菜单 “项目”的最下面 工程属性 菜单 ...

  9. MFC消息机制

    何谓消息.消息处理函数.消息映射?消息简单的说就是指通过输入设备向程序发出指令要执行某个操作.具体的某个操作是你的一系列代码.称为消息处理函数. 在SDK中消息其实非常容易理解,当窗口建立后便会有一个 ...

  10. HTTP 返回状态值详解

    当用户点击或搜索引擎向网站服务器发出浏览请求时,服务器将返回Http Header Http头信息状态码,常见几种如下: 1.Http/1.1 200 OK 访问正常  表示成功访问,为网站可正常访问 ...