`
j小虫
  • 浏览: 18872 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

阻塞队列

阅读更多

阻塞队列是jdk1.5新特性,本质就是一个队列,当队列为空时,消费方阻塞等待,直到队列有新的对象;队列满了时,生产方阻塞等待,直到队列有空位时;它实现了多线程的排队等待。

队列,Queue接口,有先进先出的特性,与List,Set在同一级别,都继承了Collection接口,而BlockingQueue继承了Queue。

 

Queue提供了以下方法:

     add,offer:add如果队列满了, 则抛出异常IIIegaISlabEepeplian,offer如果满则返回false

     remove,poll:移除一个元素,为空时,remove抛异常NoSuchElementException,poll返回null,可以配合queue的size作循环

 

 

BlockingQueue提供了以下方法

      put:类似add方法,但队列满了不抛异常,直接等待。

      take:类似poll方法,队列空时不返回null,直接阻塞等待。

 

Blocking队列分为4种

LinkedBlockingQueue 的容量是没有上限的(说的不准确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),但是也可以选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。

ArrayBlockingQueue 在构造时需要指定容量,并可以选择是否需要公平性,如果公平参数被设置 true,等待时间最长的线程会优先得到处理(其实就是通过将ReentrantLock设置为true来达到这种公平性的:即等待时间最长的线程会先操 作)。通常,公平性会使你在性能上付出代价,只有在的确非常需要的时候再使用它。它是基于数组的阻塞循环队列,此队列按 FIFO(先进先出)原则对元素进行排序

PriorityBlockingQueue 是一个带优先级的队列,而不是先进先出队列。元素按优先级顺序被移除,该 队列也没有上限(看了一下源码,PriorityBlockingQueue是对PriorityQueue的再次包装,是基于堆数据结构的,而 PriorityQueue是没有容量限制的,与ArrayList一样,所以在优先阻塞队列上put时是不会受阻的。虽然此队列逻辑上是无界的,但是由 于资源被耗尽,所以试图执行添加操作可能会导致 OutOfMemoryError),但是如果队列为空,那么取元素的操作take就会阻塞,所以它的检索操作take是受阻的。另外,往入该队列中的元 素要具有比较能力。

DelayQueue (基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不允许使用 null 元素。 下面是延迟接口:

  1. public   interface  Delayed  extends  Comparable<Delayed> {  
  2.      long  getDelay(TimeUnit unit);  

 

使用阻塞队列两个显著的好处就是:多线程操作共同的队列时不需要额外的同步,另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减少两边的处理速度差距

 

 

最后copy了一段代码示例

  1. public   class  BlockingQueueTest {  
  2.     public   static   void  main(String[] args) {  
  3.         Scanner in = new  Scanner(System.in);  
  4.         System.out.print("Enter base directory (e.g. /usr/local/jdk5.0/src): " );  
  5.         String directory = in.nextLine();  
  6.         System.out.print("Enter keyword (e.g. volatile): " );  
  7.         String keyword = in.nextLine();  
  8.   
  9.         final   int  FILE_QUEUE_SIZE =  10 ; // 阻塞队列大小   
  10.         final   int  SEARCH_THREADS =  100 ; // 关键字搜索线程个数   
  11.   
  12.         // 基于ArrayBlockingQueue的阻塞队列   
  13.         BlockingQueue<File> queue = new  ArrayBlockingQueue<File>(  
  14.                 FILE_QUEUE_SIZE);  
  15.   
  16.         //只启动一个线程来搜索目录   
  17.         FileEnumerationTask enumerator = new  FileEnumerationTask(queue,  
  18.                 new  File(directory));  
  19.         new  Thread(enumerator).start();  
  20.           
  21.         //启动100个线程用来在文件中搜索指定的关键字   
  22.         for  ( int  i =  1 ; i <= SEARCH_THREADS; i++)  
  23.             new  Thread( new  SearchTask(queue, keyword)).start();  
  24.     }  
  25. }  
  26. class  FileEnumerationTask  implements  Runnable {  
  27.     //哑元文件对象,放在阻塞队列最后,用来标示文件已被遍历完   
  28.     public   static  File DUMMY =  new  File( "" );  
  29.   
  30.     private  BlockingQueue<File> queue;  
  31.     private  File startingDirectory;  
  32.   
  33.     public  FileEnumerationTask(BlockingQueue<File> queue, File startingDirectory) {  
  34.         this .queue = queue;  
  35.         this .startingDirectory = startingDirectory;  
  36.     }  
  37.   
  38.     public   void  run() {  
  39.         try  {  
  40.             enumerate(startingDirectory);  
  41.             queue.put(DUMMY);//执行到这里说明指定的目录下文件已被遍历完   
  42.         } catch  (InterruptedException e) {  
  43.         }  
  44.     }  
  45.   
  46.     // 将指定目录下的所有文件以File对象的形式放入阻塞队列中   
  47.     public   void  enumerate(File directory)  throws  InterruptedException {  
  48.         File[] files = directory.listFiles();  
  49.         for  (File file : files) {  
  50.             if  (file.isDirectory())  
  51.                 enumerate(file);  
  52.             else   
  53.                 //将元素放入队尾,如果队列满,则阻塞   
  54.                 queue.put(file);  
  55.         }  
  56.     }  
  57. }  
  58. class  SearchTask  implements  Runnable {  
  59.     private  BlockingQueue<File> queue;  
  60.     private  String keyword;  
  61.   
  62.     public  SearchTask(BlockingQueue<File> queue, String keyword) {  
  63.         this .queue = queue;  
  64.         this .keyword = keyword;  
  65.     }  
  66.   
  67.     public   void  run() {  
  68.         try  {  
  69.             boolean  done =  false ;  
  70.             while  (!done) {  
  71.                 //取出队首元素,如果队列为空,则阻塞   
  72.                 File file = queue.take();  
  73.                 if  (file == FileEnumerationTask.DUMMY) {  
  74.                     //取出来后重新放入,好让其他线程读到它时也很快的结束   
  75.                     queue.put(file);  
  76.                     done = true ;  
  77.                 } else   
  78.                     search(file);  
  79.             }  
  80.         } catch  (IOException e) {  
  81.             e.printStackTrace();  
  82.         } catch  (InterruptedException e) {  
  83.         }  
  84.     }  
  85.     public   void  search(File file)  throws  IOException {  
  86.         Scanner in = new  Scanner( new  FileInputStream(file));  
  87.         int  lineNumber =  0 ;  
  88.         while  (in.hasNextLine()) {  
  89.             lineNumber++;  
  90.             String line = in.nextLine();  
  91.             if  (line.contains(keyword))  
  92.                 System.out.printf("%s:%d:%s%n" , file.getPath(), lineNumber,  
  93.                         line);  
  94.         }  
  95.         in.close();  
  96.     }  

分享到:
评论

相关推荐

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

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

    java模拟阻塞队列

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

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

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

    并发-线程池和阻塞队列.pdf

    线程池和阻塞队列是实现并发的关键组件之一。本文将详细介绍线程池原理、使用场景及注意事项,以及阻塞队列的相关知识。 首先,线程池是一种基于池化思想管理线程的技术,它可以重用一组线程执行多个任务。线程池的...

    c++11 实现的阻塞队列

    C++11 实现的阻塞队列 C++11 中的阻塞队列是指在多线程环境下,实现生产者消费者模式的队列。阻塞队列的实现需要解决两个问题:线程安全和阻塞机制。在 C++11 中,我们可以使用 std::mutex、std::condition_...

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

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

    BlockingQueue(阻塞队列)详解

    ### BlockingQueue(阻塞队列)详解 #### 一、前言 随着现代软件系统对并发性能需求的不断提高,多线程编程技术逐渐成为开发人员不可或缺的技能之一。在Java平台中,`java.util.concurrent`包提供了丰富的工具来...

    Java实现简单的阻塞队列2种方式

    在Java编程中,阻塞队列是一种特殊类型的并发数据结构,它在多线程环境中的应用广泛,主要用于线程间的协作通信。阻塞队列在队列满时会阻止生产者线程添加元素,在队列空时会阻止消费者线程取出元素,直到条件满足...

    生产者/消费者模式 阻塞队列 LinkedBlockingQueue

    在Java中,阻塞队列(BlockingQueue)是一个很好的实现生产者/消费者模式的工具,而LinkedBlockingQueue则是Java并发包(java.util.concurrent)中提供的一个具体实现。 LinkedBlockingQueue是一个基于链表结构的...

    并发-线程池和阻塞队列

    在Java编程中,"并发-线程池和阻塞队列"是两个核心概念,它们在多线程环境下处理任务调度和数据同步方面发挥着重要作用。线程池是一种管理线程资源的有效方式,而阻塞队列则常用于线程间通信和数据共享。 线程池...

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

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

    阻塞队列(Blocking Queue)是一个支持两个附加操作的队列.txt

    阻塞队列是Java中并发编程的一个重要组件,它属于Java.util.concurrent包中的一部分。阻塞队列的主要特点在于它支持两个额外的条件操作:当队列为空时,尝试从队列中取元素的操作会被阻塞,直到队列中出现新的元素;...

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

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

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

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

    高性能阻塞队列的数据结构创新.pptx

    ### 高性能阻塞队列的数据结构创新 #### 一、阻塞队列的概念与应用 **阻塞队列**是一种特殊的队列,它具备线程安全的特点,并且当队列为空时,从队列中获取元素的操作会被阻塞;同样地,当队列满时,向队列中添加...

    Java并发编程(21)并发新特性-阻塞队列和阻塞栈(含代

    在Java并发编程中,阻塞队列和阻塞栈是两个重要的并发数据结构,它们在多线程环境下的高效通信和资源管理中扮演着至关重要的角色。这些数据结构源自Java的并发包`java.util.concurrent`,是实现并发设计模式如生产者...

    阻塞队列实现生产者消费者模式Java开发Java经验技巧共

    在这个场景中,阻塞队列(BlockingQueue)是实现这种模式的理想工具,因为它提供了线程安全的数据同步机制。 阻塞队列在Java中的实现主要由`java.util.concurrent`包下的几个类提供,如`ArrayBlockingQueue`、`...

    java阻塞队列实现原理及实例解析.docx

    Java 阻塞队列(Blocking Queue)是一种特殊类型的并发数据结构,它在多线程编程中扮演着重要的角色。阻塞队列的核心特性在于其在队列为空或满时能够自动阻塞线程,从而实现线程间的同步和通信。这种机制使得生产者...

    剖析Java中阻塞队列的实现原理及应用场景

    Java中的阻塞队列是一种特殊的线程安全的数据结构,它在多线程环境下用于高效地处理生产者-消费者问题。阻塞队列的核心特性在于当队列为空时,尝试获取元素的线程会被阻塞,直到队列中有元素可用;同样,当队列满时...

    java学习(基于Java阻塞队列的搜索实例).pdf

    在这篇文档中,我们将详细探讨Java中基于阻塞队列的搜索实例。Java的并发API为我们提供了强大的线程间通信工具,而阻塞队列是这些工具中的核心组件之一。阻塞队列是一个支持两个附加操作的队列:在队列为空时,获取...

Global site tag (gtag.js) - Google Analytics