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

本文由 TonySpark 翻译自 Javarevisited转载请参见文章末尾的要求。

Java.util.concurrent.BlockingQueue 是一个队列实现类,支持这样的操作:当从队列中获取或者移除元素时,如果队列为空,需要等待,直到队列不为空;同时如果向队列中添加元素时,此时如果队列无可用空间,也需要等待。

BlockingQueue 类不接收Null值,如果你试图向队列中存入Null值将抛出NullPointerException.

BlockingQueue的实现是线程安全的。所有队列方法本身都是原子操作,使用并发控制的内部锁或者其它形式。

BlockingQueue这个接口是Java集合架构的一部分,它主要用于解决生产者/消费者问题。在BlockingQueue中,我们不用担心生产者操作时是否有可用空间或者消费者操作时是否有可用的对像而等待这样的问题,这些都会在它的实现类中进行处理。

Java中提供了几个对BlockingQueue的实现类,如: ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue 等

在处理生产者/消费者问题上 我们将会使用ArrayBlockingQueue来实现,如下是我们需知道的重要方法:

  • put(E e): 这个方法用于向队列中插入元素,如果队列已满,需要等待可用的这间。
  • E take(): 这个方法用于从队列头部获取或者移除元素,如果队列为空则需要等待可用的元素。

现在咱们看看用BlockingQueue来解决生产者/消费者问题。

Message

Producer产生的普通Java对象,并添加到队列中。

Message.java

 1 package com.journaldev.concurrency;
 2
 3 public class Message {
 4     private String msg;
 5
 6     public Message(String str){
 7         this.msg=str;
 8     }
 9
10     public String getMsg() {
11         return msg;
12     }
13
14 }

Producer

Producer这个类会产生消息并将其放入队列中。

Producer.java

package com.journaldev.concurrency;import java.util.concurrent.BlockingQueue;public class Producer implements Runnable {private BlockingQueue<Message> queue;public Producer(BlockingQueue<Message> q){this.queue=q;}@Overridepublic void run() {//生产消息for(int i=0; i<100; i++){Message msg = new Message(""+i);try {Thread.sleep(i);queue.put(msg);System.out.println("Produced "+msg.getMsg());} catch (InterruptedException e) {e.printStackTrace();}}//添加退出消息Message msg = new Message("exit");try {queue.put(msg);} catch (InterruptedException e) {e.printStackTrace();}}}

Consumer

Consumer类会从队列获取消息进行处理。如果获取的是退出消息则结束。

Consumer.java

package com.journaldev.concurrency;import java.util.concurrent.BlockingQueue;public class Consumer implements Runnable{private BlockingQueue<Message> queue;public Consumer(BlockingQueue<Message> q){this.queue=q;}@Overridepublic void run() {try{Message msg;//获取并处理消息直到接收到“exit”消息while((msg = queue.take()).getMsg() !="exit"){Thread.sleep(10);System.out.println("Consumed "+msg.getMsg());}}catch(InterruptedException e) {e.printStackTrace();}}
}

ProducerConsumerService

生产者/消费者的服务类将会产生固定大小的BlockingQueue,生产者和消费者同时共享该BlockingQueue,该服务类会起启动生产者和消费者线程。

ProducerConsumerService.java

 1 package com.journaldev.concurrency;
 2
 3
 4 import java.util.concurrent.ArrayBlockingQueue;
 5 import java.util.concurrent.BlockingQueue;
 6
 7
 8 public class ProducerConsumerService {
 9
10     public static void main(String[] args) {
11         //创建大小为10的 BlockingQueue
12         BlockingQueue<Message> queue = new ArrayBlockingQueue<>(10);
13         Producer producer = new Producer(queue);
14         Consumer consumer = new Consumer(queue);
15         //开启 producer线程向队列中生产消息
16         new Thread(producer).start();
17         //开启 consumer线程 中队列中消费消息
18         new Thread(consumer).start();
19         System.out.println("Producer and Consumer has been started");
20     }
21
22 }

上面程序的运行结果:

 1 Producer and Consumer has been started
 2 Produced 0
 3 Produced 1
 4 Produced 2
 5 Produced 3
 6 Produced 4
 7 Consumed 0
 8 Produced 5
 9 Consumed 1
10 Produced 6
11 Produced 7
12 Consumed 2
13 Produced 8
14 ...

Thread sleep 使得生产者/消费者 生产、消费这此消息有一定的延迟。

原文链接: Javarevisited 翻译: TonySpark
译文链接: http://www.cnblogs.com/tonyspark/p/3722013.html

转载请保留原文出处、译者和译文链接。]

转载于:https://www.cnblogs.com/tonyspark/p/3722013.html

Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例相关推荐

  1. 什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...

  2. Java 阻塞队列--BlockingQueue

    1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...

  3. 用阻塞队列LinkedBlockingQueue实现生产者消费者先进先出

    LinkedBlockingQueue是一个基于已链接节点的.范围任意的blocking queue的实现. 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生 ...

  4. Java阻塞队列-BlockingQueue介绍及实现原理

    阻塞队列是对普通队列的一种扩展,在普通队列功能上增加了一些额外功能. 普通队列的功能可以参照java的Queue接口 public interface Queue<E> extends C ...

  5. java阻塞队列的使用

    一.阻塞队列的作用 阻塞队列(BlockingQueue),顾名思义,首先它是一个队列,而一个阻塞队列在数据结构中所起的作用大致如图所示: 当阻塞队列是空时,从队列中获取元素的操作将会被阻塞 当阻塞队 ...

  6. 抽象同步器AQS应用之--阻塞队列BlockingQueue,如何保证任务一定被消费?

    文章目录 1.阻塞队列简介 2. BlockingQueue源码分析 3. 生产者消费者模型如何保证信息不会丢失? 1.阻塞队列简介 1.1 什么是阻塞队列? 阻塞队列是一个队列 ①:当队列是空的,从 ...

  7. java 阻塞队列 BQ_阻塞队列 BlockingQueue的使用(二)

    原 阻塞队列 BlockingQueue的使用(二) BlockingQueue 的核心方法:方法类型抛出异常特殊值阻塞超时 插入add(e)offer(e)put(e)offer(e,time,un ...

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

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

  9. java阻塞队列作用_简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用...

    简单理解阻塞队列(BlockingQueue)中的take/put方法以及Condition存在的作用 Condition:可以理解成一把锁的一个钥匙,它既可以解锁(通知放行),又可以加锁(阻塞) n ...

最新文章

  1. hibernate注解之@Onetomany、@Manytoone、@JoinColumn
  2. 记事本写python怎么运行-利用Python开发实现简单的记事本
  3. PMCAFF|盘点2016最值得突击的七大海外市场:最后一年窗口期,不出海就出局!...
  4. php server script name,$_SERVER[SCRIPT_NAME]变量可值注入恶意代码
  5. php网页的注册界面设计,HTML开发博客之注册页面设计(一)
  6. html背景动起来,CSS+HTML 循环滚动背景效果
  7. ssis 创建ssisdb_使用SSIS创建备份
  8. Hadoop 环境准备
  9. java 利用Future异步获取多线程任务结果
  10. 计算机切换到桌面,电脑桌面切换软件 电脑桌面快速切换
  11. java 流 flush,在Java流中flush()的目的是什么?
  12. 国考银保监会计算机类笔试,银保监会(计算机类)笔试资料(含2018-2019真题).zip...
  13. python中random.sample()函数
  14. SpringBoot(三)配置文件
  15. threejs粒子效果
  16. 超分辨率 | 综述!使用深度学习来实现图像超分辨率
  17. 攻防世界_Crypto_Decrypt-the-Message
  18. 关于srand()与rand()函数的理解-----必看系列
  19. Go MD5加密解密用法
  20. WinRAR误装其他语言版本卸载重装后右键依旧存在外文

热门文章

  1. 如何将项目上传到GitHub
  2. codeforces 1029 A. Many Equal Substrings
  3. oc 中随机数的用法(arc4random() 、random()、CCRANDOM_0_1()
  4. 封装事件绑定函数解决this在ie下的绑定问题
  5. 【译】史上最强的vimrc文件
  6. Asp.net中防止用户多次登录的方法
  7. 使用shouldComponentUpdate进行性能优化
  8. swift:简单使用翻页控制器UIPageViewController
  9. IOS-TextField控件详解
  10. 想拥有最新的微软嵌入式技术 就赶快加入微软嵌入式专家社区吧!