阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue

LinkedBlockingQueue:

public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, Serializable  

此队列按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素。

链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。

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

Demo:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class Main {
    public static void main(String[] args) {
        // 建立一个装苹果的篮子
        Basket basket =  new Basket();
        ExecutorService service = Executors.newCachedThreadPool();
        Producer producer =  new Producer("生产者001", basket);
        Producer producer2 =  new Producer("生产者002", basket);
        Consumer consumer =  new Consumer("消费者001", basket);
        service.submit(producer);
        service.submit(producer2);
        service.submit(consumer);
        // 程序运行5s后,所有任务停止
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.shutdownNow();

    }
}

/**
 *
 * 定义装苹果的篮子
 *
 */
class Basket {
    // 篮子,能够容纳3个苹果
    BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3);
    int i=0;
    // 生产苹果,放入篮子
    public void produce() throws InterruptedException {
        // put方法放入一个苹果,若basket满了,等到basket有位置
        i++;
        basket.put("An apple"+i);
    }

    // 消费苹果,从篮子中取走
    public String consume() throws InterruptedException {
        // take方法取出一个苹果,若basket为空,等到basket有苹果为止(获取并移除此队列的头部)
        return basket.take();
    }
}

// 定义苹果生产者
class Producer implements Runnable {
    private String instance;
    private Basket basket;

    public Producer(String instance, Basket basket) {
        this.instance = instance;
        this.basket = basket;
    }

    public void run() {
        try {
            while (true) {
                // 生产苹果
                System.out.println("生产者准备生产苹果:" + instance);
                basket.produce();
                System.out.println("!生产者生产苹果完毕:" + instance);
                // 休眠300ms
                Thread.sleep(300);
            }
        } catch (InterruptedException ex) {
            System.out.println("Producer Interrupted");
        }
    }
}

// 定义苹果消费者
class Consumer implements Runnable {
    private String instance;
    private Basket basket;

    public Consumer(String instance, Basket basket) {
        this.instance = instance;
        this.basket = basket;
    }

    public void run() {
        try {
            while (true) {
                // 消费苹果
                System.out.println("消费者准备消费苹果:" + instance);
                System.out.println(basket.consume());
                System.out.println("!消费者消费苹果完毕:" + instance);
                // 休眠1000ms
                Thread.sleep(1000);
            }
        } catch (InterruptedException ex) {
            System.out.println("Consumer Interrupted");
        }
    }
}

生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
生产者准备生产苹果:生产者002
!生产者生产苹果完毕:生产者002
!生产者生产苹果完毕:生产者001
An apple1
!消费者消费苹果完毕:消费者001
生产者准备生产苹果:生产者001
生产者准备生产苹果:生产者002
!生产者生产苹果完毕:生产者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者001
生产者准备生产苹果:生产者002
消费者准备消费苹果:消费者001
An apple2
!生产者生产苹果完毕:生产者001
!消费者消费苹果完毕:消费者001
生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
An apple3
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者002
消费者准备消费苹果:消费者001
An apple4
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者001
生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
An apple5
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者002
Producer Interrupted
Producer Interrupted
Consumer Interrupted

http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html

http://blog.csdn.net/ac903919/article/details/6967728

时间: 2024-10-11 18:34:54

阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue的相关文章

同步,异步,串行队列,并发队列,全局队列,主队列等概念的总结

同步,异步,串行队列,并发队列,全局队列,主队列等概念的总结 在GCD函数中, 我们常常碰到同步,异步,串行队列,并发队列,全局队列,主队列等概念,而这些概念又常常组合在一起, 十分头疼, 这篇文章就来梳理一下这些烦人的概念. 不想看长篇大论的, 直接看文章末尾的表格即可! 在此之前, GCD中还涉及到两个十分重要的概念, 就是任务和队列 任务(Task): 你需要执行的操作 队列(Queue): 存放任务的容器 GCD中两个重要的函数, 一个同步执行, 一个异步执行 dispatch_asyn

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列. 注:什么叫线程安全?这个首先要明确.线程安全就是说多线程访问同一代码,不会产生不确定的结果. 并行和并发区别 1.并行是指两者同时执行一件事,比如赛跑,两个人都在不停的

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

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列,都不能存放null值. 1.BlockingQueue下有两个常用子类LinkedBlockingQueue和ArrayBlockingQueue,内部分链表和数组实现,

并发队列之:BlockingQueue和ConcurrentLinkedQueue

一.并行和并发区别: 并行:是指两者同时执行一件事.比如赛跑,两个人都在不停的往前跑: 并发:是指资源有限的情况下,两者交替轮流使用资源.比如一段路(单核CPU资源)同时只能过一个人,A走一段后,让给B,B用完继续给A ,交替使用,目的是提高效率. 二.什么叫线程安全 线程安全就是说多线程访问同一代码,不会产生不确定的结果. 反之线程不安全就是,多线程在访问同一代码时,会发生不确定因素,例如死锁,数据不一致性等. 三.LinkedBlockingQueue LinkedBlockingQueue

线程队列之阻塞队列LinkedBlockingQueue

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列. 注:什么叫线程安全?这个首先要明确.线程安全就是说多线程访问同一代码,不会产生不确定的结果. 并行和并发区别 1.并行是指两者同时执行一件事,比如赛跑,两个人都在不停的

阻塞队列和并发队列

在并发编程中我们有时候需要使用线程安全的队列.要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法. 使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,其中阻塞队列的典型是:BlockingQueue; 非阻塞的实现方式则可以使用循环CAS的方式来实现,非阻塞队列的典型例子是ConcurrentLinkedQueue. 注:并行与并发的区别: 1.并行是指两者同时执行一件事,比如赛跑,两个人都在不停的往前跑: 2.并

多线程编程:阻塞、并发队列的使用总结

最近,一直在跟设计的任务调度模块周旋,目前终于完成了第一阶段的调试.今天,我想借助博客园平台把最近在设计过程中,使用队列和集合的一些基础知识给大家总结一下,方便大家以后直接copy.本文都是一些没有技术含量的东西,只是做个总结,牛哥还请绕路. 老习惯,还是先跟各位纸上谈会儿兵,首先说说队列,他主要分为并发队列和阻塞队列,在多线程业务场景中使用最为普遍,我就主要结合我所做过的业务谈谈我对它们的看法,关于它们的API和官方解释就不提了. 并发队列 并发队列:最常见的业务场景就是多个线程共享同一个队列

并发队列之LinkedBlockingQueue

上一篇我们看了一下这个队列ConcurrentLinkedQueue,那就是一个无界非阻塞链表,我们这次来看看LinkedBlockingQueue,这个队列看名字就知道是一个阻塞式队列(也就是一个单向链表),基于独占锁实现的,比较简单: 一.LinkedBlockingQueue基本结构 内部也是有一个Node类,下图所示,item存 实际数据,next指向下一个节点,一个有参构造器,没啥好说的: 我们可以看看这个队列有的一些属性,其实大概能猜出来就是生产者消费者模型: //队列实际容量 pr

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

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