`

(转)Java线程(篇外篇):阻塞队列BlockingQueue

 
阅读更多

  好久没有写文章了,这段时间事情比较杂,工作也比较杂乱,上周日刚搬完家,从自建房搬到了楼房,提升了一层生活品质,哈哈!不过昨天晚上在公交车上钱包被偷了,前段时间还丢个自行车,不得不感叹,京城扒手真多,还无人处理。言归正传,这一段时间我的工作主要是改进公司的调度器,调度器调度线程池执行任务,生产者生产任务,消费者消费任务,那么这时就需要一个任务队列,生产者向队列里插入任务,消费者从队列里提取任务执行,调度器里是通过BlockingQueue实现的队列,随后小查一下,下面看看BlockingQueue的原理及其方法。

       BlockingQueue最终会有四种状况,抛出异常、返回特殊值、阻塞、超时,下表总结了这些方法:

 

  抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 不可用

 

 

       BlockingQueue是个接口,有如下实现类:

       1. ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。

       2. LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 

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

       4. SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然。

       下面使用ArrayBlockQueue来实现之前实现过的生产者消/费者模式,代码如下:

 

[java] view plaincopy
 
  1. /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */  
  2. public class BigPlate {  
  3.   
  4.     /** 装鸡蛋的盘子,大小为5 */  
  5.     private BlockingQueue<Object> eggs = new ArrayBlockingQueue<Object>(5);  
  6.       
  7.     /** 放鸡蛋 */  
  8.     public void putEgg(Object egg) {  
  9.         try {  
  10.             eggs.put(egg);// 向盘子末尾放一个鸡蛋,如果盘子满了,当前线程阻塞  
  11.         } catch (InterruptedException e) {  
  12.             e.printStackTrace();  
  13.         }  
  14.   
  15.         // 下面输出有时不准确,因为与put操作不是一个原子操作  
  16.         System.out.println("放入鸡蛋");  
  17.     }  
  18.       
  19.     /** 取鸡蛋 */  
  20.     public Object getEgg() {  
  21.         Object egg = null;  
  22.         try {  
  23.             egg = eggs.take();// 从盘子开始取一个鸡蛋,如果盘子空了,当前线程阻塞  
  24.         } catch (InterruptedException e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.   
  28.         // 下面输出有时不准确,因为与take操作不是一个原子操作  
  29.         System.out.println("拿到鸡蛋");  
  30.         return egg;  
  31.     }  
  32.       
  33.     /** 放鸡蛋线程 */  
  34.     static class AddThread extends Thread {  
  35.         private BigPlate plate;  
  36.         private Object egg = new Object();  
  37.   
  38.         public AddThread(BigPlate plate) {  
  39.             this.plate = plate;  
  40.         }  
  41.   
  42.         public void run() {  
  43.             plate.putEgg(egg);  
  44.         }  
  45.     }  
  46.   
  47.     /** 取鸡蛋线程 */  
  48.     static class GetThread extends Thread {  
  49.         private BigPlate plate;  
  50.   
  51.         public GetThread(BigPlate plate) {  
  52.             this.plate = plate;  
  53.         }  
  54.   
  55.         public void run() {  
  56.             plate.getEgg();  
  57.         }  
  58.     }  
  59.       
  60.     public static void main(String[] args) {  
  61.         BigPlate plate = new BigPlate();  
  62.         // 先启动10个放鸡蛋线程  
  63.         for(int i = 0; i < 10; i++) {  
  64.             new Thread(new AddThread(plate)).start();  
  65.         }  
  66.         // 再启动10个取鸡蛋线程  
  67.         for(int i = 0; i < 10; i++) {  
  68.             new Thread(new GetThread(plate)).start();  
  69.         }  
  70.     }  
  71. }  

       执行结果:

 

 

[plain] view plaincopy
 
  1. 放入鸡蛋  
  2. 放入鸡蛋  
  3. 放入鸡蛋  
  4. 放入鸡蛋  
  5. 放入鸡蛋  
  6. 拿到鸡蛋  
  7. 放入鸡蛋  
  8. 拿到鸡蛋  
  9. 拿到鸡蛋  
  10. 拿到鸡蛋  
  11. 放入鸡蛋  
  12. 放入鸡蛋  
  13. 放入鸡蛋  
  14. 拿到鸡蛋  
  15. 放入鸡蛋  
  16. 拿到鸡蛋  
  17. 拿到鸡蛋  
  18. 拿到鸡蛋  
  19. 拿到鸡蛋  
  20. 拿到鸡蛋  

       从结果看,启动10个放鸡蛋线程和10个取鸡蛋线程,前5个放入鸡蛋的线程成功执行,到第6个,发现盘子满了,阻塞住,这时切换到取鸡蛋线程执行,成功实现了生产者/消费者模式。java.util.concurrent包是个强大的包!

 

        本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/8108292

分享到:
评论

相关推荐

    14-阻塞队列BlockingQueue实战及其原理分析二.pdf

    阻塞队列(BlockingQueue)是一种特殊的队列,它支持两个附加操作:阻塞的插入方法put和阻塞的移除方法take。BlockingQueue继承了Queue接口,是Java 5中加入的。 BlockingQueue常用方法示例: 1. add(E e):添加一...

    BlockingQueue(阻塞队列)详解

    - **定义**:阻塞队列是一种特殊的队列,除了具有队列的基本特性外,还提供了额外的阻塞行为,即当队列空时,从队列中获取元素的操作将会阻塞,等待队列变得非空;当队列满时,向队列插入元素的操作也会阻塞,等待...

    BlockingQueue队列自定义超时时间取消线程池任务

    首先,`BlockingQueue`是一个并发容器,它遵循先进先出(FIFO)原则,具有阻塞性质,当队列满时,生产者线程会被阻塞,直到有消费者取走元素;当队列空时,消费者线程会被阻塞,直到生产者放入新的元素。常用实现如`...

    java中线程队列BlockingQueue的用法

    在Java编程中,`BlockingQueue`(阻塞队列)是一种重要的并发工具,它结合了队列的数据结构和线程同步机制。`BlockingQueue`接口位于`java.util.concurrent`包中,提供了线程安全的数据结构,可以用于实现生产者-...

    支持多线程和泛型的阻塞队列

    阻塞队列是一种在多线程编程中广泛使用的并发数据结构,它在计算机科学和编程领域,特别是Java和C++等面向对象语言中扮演着重要角色。标题中的“支持多线程和泛型的阻塞队列”意味着我们讨论的是一个能够同时处理多...

    10、阻塞队列BlockingQueue实战及其原理分析

    阻塞队列BlockingQueue是Java并发编程中一个重要的数据结构,它是线程安全的队列,主要用于生产者消费者模型中的数据交换。在Java的`java.util.concurrent`包中,提供了多种实现阻塞队列的类,如`ArrayBlockingQueue...

    java线程聊天室(阻塞队列实现)

    【Java线程聊天室(阻塞队列实现)】 在Java编程中,多线程是构建并发应用程序的关键技术。在创建一个线程聊天室时,我们通常会涉及到多个线程之间的交互,例如用户发送消息、接收消息以及处理网络通信等。而阻塞...

    10、阻塞队列BlockingQueue实战及其原理分析.pdf

    ### 10、阻塞队列BlockingQueue 实战及其原理分析 #### 一、阻塞队列概述 阻塞队列(BlockingQueue)是Java语言中`java.util.concurrent`包下提供的一种重要的线程安全队列。它继承自`Queue`接口,并在此基础上...

    java多线程加队列上传文件_后台处理

    ### Java多线程加队列上传文件_后台处理 #### 概述 本文将详细介绍一个基于Java实现的多线程文件上传系统,并结合队列管理技术来优化后台处理流程。该系统通过创建多个线程来并行处理客户端的文件上传请求,同时...

    java 多线程 队列工厂

    `java.util.concurrent.BlockingQueue`是Java并发库中的一个重要接口,它扩展了`Queue`接口,增加了线程安全的阻塞操作。阻塞队列在多线程环境中特别有用,因为它允许线程在队列满时等待,直到有空间可用;同样,当...

    java模拟阻塞队列

    Java中的阻塞队列是一种基于同步原语的高级数据结构,它在多线程编程中扮演着重要角色,尤其在并发处理和优化系统资源利用率方面。阻塞队列结合了队列的数据结构与线程同步机制,使得生产者可以在队列满时被阻塞,而...

    Java_多线程编程线程:大总结

    - **新特征**:Java 5引入的并发工具,如`ConcurrentHashMap`、`CountDownLatch`、`CyclicBarrier`、`Semaphore`、`BlockingQueue`等,极大地简化了多线程编程的复杂度。 #### 五、Java线程的新特征详解 - **...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    - **线程的创建**:Java提供了两种创建线程的方式,一是通过实现`Runnable`接口,二是继承`Thread`类。每种方式都有其适用场景,需要根据实际需求选择。 - **生命周期**:线程有新建、就绪、运行、阻塞和终止五种...

    java线程实例 各种小Demo

    Java 5引入了BlockingQueue阻塞队列,提供了一种更安全的线程间通信方式,如ArrayBlockingQueue、LinkedBlockingQueue等。 在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过...

    阻塞队列阻塞队列阻塞队列

    在Java编程语言中,阻塞队列是一种线程安全的数据结构,它在多线程并发控制中发挥着重要作用。阻塞队列的核心特性是当队列为空时,尝试获取元素的线程会被阻塞,直到其他线程添加元素;同样,当队列满时,试图插入...

    java 中 阻塞队列BlockingQueue详解及实例

    Java中的阻塞队列BlockingQueue是一种并发编程中常用的工具,它实现了线程间的同步和通信。阻塞队列的核心特性在于当队列为空时,尝试获取元素的线程会被阻塞,直到其他线程添加元素;当队列满时,尝试添加元素的...

    Java多线程编程实战指南-核心篇

    Java的BlockingQueue阻塞队列可以实现线程间的生产者-消费者模式,通过put()和take()方法实现数据的传递。此外,Phaser、CyclicBarrier和CountDownLatch等同步辅助类也是线程间协调的重要工具。 线程池是Java并发...

    java线程api学习文档

    - `BlockingQueue`: 阻塞队列,用于线程间的数据传递,当队列为空时,取元素的线程会被阻塞,直到有元素添加。 了解并熟练掌握这些Java线程API将有助于编写高效、可维护的多线程程序。通过深入阅读"Java线程.pdf...

    java线程入门,java线程入门

    - **BlockingQueue**:提供一种线程安全的数据结构,线程间可以通过队列进行数据交换。 6. **线程池**: - **Executor框架**:Java 5引入的ExecutorService、ThreadPoolExecutor等类,提供线程池管理,减少线程...

Global site tag (gtag.js) - Google Analytics