java 阻塞队列

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
    本例介绍一个特殊的队列:BlockingQueue,如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒.同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作.
    本例再次实现11.4线程----条件Condition中介绍的篮子程序,不过这个篮子中最多能放的苹果数不是1,可以随意指定.当篮子满时,生产者进入等待状态,当篮子空时,消费者等待.
 */
/**
    使用BlockingQueue的关键技术点如下:
    1.BlockingQueue定义的常用方法如下:
        1)add(anObject):把anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则招聘异常
        2)offer(anObject):表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false.
        3)put(anObject):把anObject加到BlockingQueue里,如果BlockQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里面有空间再继续.
        4)poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
        5)take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到Blocking有新的对象被加入为止
    2.BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
        1)ArrayBlockingQueue:规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的.
        2)LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的
        3)PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序.
        4)SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的.
    3.LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue.
 */
public class BlockingQueueTest {
       /**定义装苹果的篮子*/
       public static class Basket{
              //篮子,能够容纳3个苹果
              BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);
              //生产苹果,放入篮子
              public void produce() throws InterruptedException{
                     //put方法放入一个苹果,若basket满了,等到basket有位置
                     basket.put("An apple");
              }
              //消费苹果,从篮子中取走
              public String consume() throws InterruptedException{
                     //take方法取出一个苹果,若basket为空,等到basket有苹果为止
                     return basket.take();
              }
       }
       //测试方法
       public static void testBasket(){
              final Basket basket = new Basket();//建立一个装苹果的篮子
              //定义苹果生产者
              class Producer implements Runnable{
                     public void run(){
                            try{
                                   while(true){
                                          //生产苹果
                                          System.out.println("生产者准备生产苹果: " + System.currentTimeMillis());
                                          basket.produce();
                                          System.out.println("生产者生产苹果完毕: " + System.currentTimeMillis());
                                          //休眠300ms
                                          Thread.sleep(300);
                                   }
                            }catch(InterruptedException ex){
                            }
                     }
              }
              //定义苹果消费者
              class Consumer implements Runnable{
                     public void run(){
                            try{
                                   while(true){
                                          //消费苹果
                                          System.out.println("消费者准备消费苹果: " + System.currentTimeMillis());
                                          basket.consume();
                                          System.out.println("消费者消费苹果完毕: " + System.currentTimeMillis());
                                          //休眠1000ms
                                          Thread.sleep(1000);
                                   }
                            }catch(InterruptedException ex){
                            }
                     }
              }
              ExecutorService service = Executors.newCachedThreadPool();
              Producer producer = new Producer();
              Consumer consumer = new Consumer();
              service.submit(producer);
              service.submit(consumer);
              //程序运行5s后,所有任务停止
              try{
                     Thread.sleep(5000);
              }catch(InterruptedException ex){

              }
              service.shutdownNow();
       }
       public static void main(String[] args){
              BlockingQueueTest.testBasket();
       }
}

原文: http://blog.csdn.net/azhao_dn/article/details/8191820

时间: 2024-10-08 16:45:59

java 阻塞队列的相关文章

java阻塞队列

对消息的处理有些麻烦,要保证各种确认.为了确保消息的100%发送成功,笔者在之前的基础上做了一些改进.其中要用到多线程,用于重复发送信息. 所以查了很多关于线程安全的东西,也看到了阻塞队列,发现这个模式很不错,可惜我目前用不到. 关于这个的讲解已经很多了,阻塞这个,就是当队列中没有数据的时候,线程读取的话会等待.当队列中的数据满的时候,线程添加数据的时候,也会等待. 有个例子很生动形象,往盘子里面放鸡蛋,只能放固定数目的.盘子里面没有鸡蛋,无法从中拿出来.当盘子里满了,也放不进去.直到被拿出去才

java 阻塞队列 LinkedBlockingQueue ArrayBlockingQueue 分析

BlockingQueue是阻塞队列接口类,该接口继承了Queue接口 BlockingQueue实现类常见的有以下几种. ArrayBlockingQueue:ArrayBlockingQueue 是一个有界的阻塞队列,其内部实现是将对象放到一个数组里.有界也就意味着,它不能够存储无限多数量的元素.它有一个同一时间能够存储元素数量的上限.你可以在对其初始化的时候设定这个上限,但之后就无法对这个上限进行修改了(译者注:因为它是基于数组实现的,也就具有数组的特性:一旦初始化,大小就无法修改). D

Java阻塞队列实现原理分析-ArrayBlockingQueue和LinkedBlockingQueue

Java中的阻塞队列接口BlockingQueue继承自Queue接口. BlockingQueue接口提供了3个添加元素方法. add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会抛出IllegalStateException异常 offer:添加元素到队列里,添加成功返回true,添加失败返回false put:添加元素到队列里,如果容量满了会阻塞直到容量不满 3个删除方法. poll:删除队列头部元素,如果队列为空,返回null.否则返回元素. remove:基于对象找到

Java阻塞队列线程集控制的实现

队列以一种先进先出的方式管理数据.如果你试图向一个已经满了的阻塞队列中添加一个元素,或是从一个空的阻塞队列中移除一个元素,将导致线程阻塞. 在多线程进行合作时,阻塞队列是很有用的工具.工作者线程可以定期的把中间结果存到阻塞队列中.而其他工作者线程把中间结果取出并在将来修改它们.队列会 自动平衡负载.如果第一个线程集运行的比第二个慢,则第二个线程集在等待结果时就会阻塞.如果第一个线程集运行的快,那么它将等待第二个线程集赶上来. 下面的程序展示了如何使用阻塞队列来控制线程集.程序在一个目录及它的所有

java阻塞队列得实现

阻塞队列与普通队列的不同在于.当队列是空的时候,从队列中获取元素的操作将会被阻塞,或者当队列满时,往队列里面添加元素将会被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素.同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作: 线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素 从5.0开始,JDK在Java.util.co

java 阻塞队列BlockingQueue

java中阻塞BlockingQueue 接口实现类中用的较多的通常是ArrayBlockingQueue,LinkedBlockingQueue.它们都是线程安全的.ArrayBlockingQueue以数组的形式存储,LinkedBlockingQueue以node节点的方式进行存储. 开发中如果队列的插入操作比较频繁建议使用LinkedBlockingQueue,因为每个node节点都有一个前后指针,插入新元素仅需要变更前后的指针引用即可, ArrayBlockingQueue插入新元素,

Java多线程 阻塞队列和并发集合

转载:大关的博客 Java多线程 阻塞队列和并发集合 本章主要探讨在多线程程序中与集合相关的内容.在多线程程序中,如果使用普通集合往往会造成数据错误,甚至造成程序崩溃.Java为多线程专门提供了特有的线程安全的集合类,通过下面的学习,您需要掌握这些集合的特点是什么,底层实现如何.在何时使用等问题. 3.1 BlockingQueue接口 java阻塞队列应用于生产者消费者模式.消息传递.并行任务执行和相关并发设计的大多数常见使用上下文. BlockingQueue在Queue接口基础上提供了额外

Java多线程-新特征-阻塞队列ArrayBlockingQueue

阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止.同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止. 有了这样的功能,就为多线程的排队等候的模型实现开辟了便捷通道,非常有用. java.util.concurrent.BlockingQueue继承了java.util.Queue接口,可

深入剖析java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入理解Java并发之synchronized实现原理 Java并发编程-无锁CAS与Unsafe类及其并发包Atomic 深入理解Java内存模型(JMM)及volatile关键字 剖析基于并发AQS的重入锁(ReetrantLock)及其Condition实现原理 剖析基于并发AQS的共