`

并发队列-BlockingQueue

 
阅读更多

转自:http://www.java3z.com/cwbwebhome/article/article20/200030.html?id=4852

 

本例介绍一个特殊的队列:BlockingQueue,如果BlockingQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒,同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间时才会被唤醒继续操作。

  本例实现一个篮子程序,不过这个篮子中最多能放得苹果数不是1,可以随意指定。当篮子满时,生产者进入等待状态,当篮子空时,消费者等待。


BlockingQueue定义的常用方法如下:

add(anObject):
    把anObject加到BlockingQueue里,如果BlockingQueue可以容纳,则返回true,否则抛出异常。

<iframe id="aswift_1" style="position: absolute; left: 0px; top: 0px;" name="aswift_1" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="336" height="280"></iframe>

offer(anObject):
    表示如果可能的话,将anObject加到BlockingQueue里,即如果BlockingQueue可以容纳,则返回true,否则返回false。

put(anObject):
     把anObject加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断直到BlockingQueue里有空间再继续。

poll(time):
    取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null。

take():
     取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的对象被加入为止。

BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类:

ArrayBlockingQueue:
    规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小。其所含的对象是以FIFO(先入先出)顺序排序的。

LinkedBlockingQueue:
     大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定。其所含的对象是以FIFO顺序排序的。

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

SynchronousQueue:
   特殊的BlockingQueue,对其的操作必须是放和取交替完成的。

LinkedBlockingQueue和ArrayBlockingQueue比较起来,它们背后所用的数据结构不一样,导致LinkedBlockingQueue的数据吞吐量要大于ArrayBlockingQueue,但在线程数量很大时其性能的可预见性低于ArrayBlockingQueue。


* 下面是用BlockingQueue来实现Producer和Consumer的例子

import java.util.concurrent.ArrayBlockingQueue;  
import java.util.concurrent.BlockingQueue;  
import java.util.concurrent.ExecutorService;  
import java.util.concurrent.Executors;  
public class BlockingQueueTest {  
  
    /** *//** 
     * 定义装苹果的篮子 
     */  
    public static class Basket{  
        // 篮子,能够容纳3个苹果   
        BlockingQueue basket = new ArrayBlockingQueue< String>(3);  
          
        // 生产苹果,放入篮子   
        public void produce() throws InterruptedException{  
            // put方法放入一个苹果,若basket满了,等到basket有位置   
            basket.put("An apple");  
        }  
        // 消费苹果,从篮子中取走   
        public String consume() throws InterruptedException{  
            // get方法取出一个苹果,若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 e) {  
        }  
        service.shutdownNow();  
    }  
  
    public static void main(String[] args) {  
        BlockingQueueTest.testBasket();  
    }  
}  

C:\java>javac BlockingQueueTest.java

C:\java>java BlockingQueueTest
生产者准备生产苹果:1356400720843
生产者生产苹果完毕:1356400720843
消费者准备消费苹果:1356400720843
消费者消费苹果完毕:1356400720859
生产者准备生产苹果:1356400721156
生产者生产苹果完毕:1356400721156
生产者准备生产苹果:1356400721468
生产者生产苹果完毕:1356400721484
生产者准备生产苹果:1356400721796
生产者生产苹果完毕:1356400721812
消费者准备消费苹果:1356400721859
消费者消费苹果完毕:1356400721875
生产者准备生产苹果:1356400722125
生产者生产苹果完毕:1356400722140
生产者准备生产苹果:1356400722468
消费者准备消费苹果:1356400722890
消费者消费苹果完毕:1356400722906
生产者生产苹果完毕:1356400722921
生产者准备生产苹果:1356400723234
消费者准备消费苹果:1356400723921
生产者生产苹果完毕:1356400723937
消费者消费苹果完毕:1356400723953
生产者准备生产苹果:1356400724250
消费者准备消费苹果:1356400724968
生产者生产苹果完毕:1356400724984
消费者消费苹果完毕:1356400724984
生产者准备生产苹果:1356400725296

分享到:
评论

相关推荐

    Java并发编程--BlockingQueue.docx

    【Java并发编程--BlockingQueue详解】 BlockingQueue 是 Java 并发包(java.util.concurrent)中的一个接口,它扩展了 Queue 接口,并引入了线程安全的特性,特别适合于多线程环境下的数据共享。 BlockingQueue 的...

    Java 多线程与并发(16-26)-JUC集合- BlockingQueue详解.pdf

    在实际应用中,`BlockingQueue`和`BlockingDeque`常被用来实现工作队列、缓存、线程池等并发组件,例如`ThreadPoolExecutor`就利用`BlockingQueue`来存储等待执行的任务。 理解`BlockingQueue`和`BlockingDeque`的...

    Java-concurrent-collections-concurrenthashmap-blockingqueue.pdf

    BlockingQueue 是 Java 并发集合框架中的一种阻塞队列实现,提供了高效的并发操作和线程安全机制。它可以实现生产者-消费者模式,用于在多线程环境中实现高效的数据生产和消费。 BlockingQueue 的特点包括: * ...

    spring-blockingqueue:用Spring Boot阻止队列

    当我们谈论"Spring BlockingQueue"时,我们实际上是在讨论如何在Spring Boot应用中使用Java并发库中的BlockingQueue接口。 BlockingQueue是一种线程安全的数据结构,它在多线程环境下的数据共享和通信中扮演着关键...

    并发容器——BlockingQueue相关类

    在Java编程中,`BlockingQueue`是一个非常重要的并发容器,它是Java并发包`java.util.concurrent`中的核心组件。`BlockingQueue`实现了一种线程安全的数据结构,它能够有效地协调生产者和消费者的动作,实现高效的...

    并发-线程池和阻塞队列

    阻塞队列(BlockingQueue)是Java并发包(java.util.concurrent)中的一个重要数据结构,它实现了队列的特性,同时具备线程安全的特性。当队列满时,添加元素的线程会被阻塞,直到队列有空位;当队列为空时,取出...

    java 线程池实现多并发队列后进先出

    在"java 线程池实现多并发队列后进先出"这个主题中,我们关注的是线程池如何利用特定类型的队列来实现后进先出(LIFO,Last-In-First-Out)的行为。通常,线程池默认使用先进先出(FIFO,First-In-First-Out)的队列...

    BlockingQueue(阻塞队列)详解

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

    java并发编程-超级大全整理

    - **JDK中的队列实现**:ConcurrentLinkedQueue(高性能非阻塞队列)和BlockingQueue(阻塞队列,包含7种实现)。 - **队列分类**:双端队列(Deque)和单端队列(如LinkedList、ArrayBlockingQueue、...

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

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

    java中线程队列BlockingQueue的用法

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

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

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

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

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

    java并发编程-构建块

    8. **并发编程模式**:包括生产者消费者模式、读写锁模式、双端队列模式等,这些模式有助于解决常见的并发编程问题。 9. **线程优先级**:Java线程有优先级设置,但并不保证优先级高的线程会先执行,因为线程调度...

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

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

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

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

    详解Java阻塞队列(BlockingQueue)的实现原理

    PriorityBlockingQueue 是一个无界的并发队列。它使用了和类java.util.PriorityQueue一样的排序规则。你无法向这个队列中插入null值。所有插入到PriorityBlockingQueue的元素必须实现java.lang.Comparable接口。因此...

    java并发学习之BlockingQueue实现生产者消费者详解

    "java并发学习之BlockingQueue实现生产者消费者详解" BlockingQueue是Java util.concurrent包下重要的数据结构,提供了线程安全的队列访问方式。在多线程应用中,常用于生产-消费场景。BlockingQueue有多种实现,...

    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    ### 并发队列 ConcurrentLinkedQueue 和阻塞队列 LinkedBlockingQueue 用法详解 #### 一、并发队列 ConcurrentLinkedQueue 概述 `ConcurrentLinkedQueue` 是 Java 并发包 `java.util.concurrent` 提供的一个高性能...

    队列分享-易群1

    在特定场景下,我们可能需要一种能够自动处理队列满或空情况的机制,这就是阻塞队列(BlockingQueue)的作用。阻塞队列在Java中由`java.util.concurrent`包中的`BlockingQueue`接口提供,它解决了在多线程环境下,...

Global site tag (gtag.js) - Google Analytics