简析SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue

2013年03月14日 09:45:48

SynchronousQueue

        SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续添加;可以认为SynchronousQueue是一个缓存值为1的阻塞队列,但是 isEmpty()方法永远返回是trueremainingCapacity() 方法永远返回是0,remove()和removeAll() 方法永远返回是false,iterator()方法永远返回空,peek()方法永远返回null

        声明一个SynchronousQueue有两种不同的方式,它们之间有着不太一样的行为。公平模式和非公平模式的区别:如果采用公平模式:SynchronousQueue会采用公平锁,并配合一个FIFO队列来阻塞多余的生产者和消费者,从而体系整体的公平策略;但如果是非公平模式(SynchronousQueue默认):SynchronousQueue采用非公平锁,同时配合一个LIFO队列来管理多余的生产者和消费者,而后一种模式,如果生产者和消费者的处理速度有差距,则很容易出现饥渴的情况,即可能有某些生产者或者是消费者的数据永远都得不到处理。

LinkedBlockingQueue

        LinkedBlockingQueue是无界的,是一个无界缓存的等待队列。

        基于链表的阻塞队列,内部维持着一个数据缓冲队列(该队列由链表构成)。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。

        LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。

ArrayListBlockingQueue

         ArrayListBlockingQueue是有界的,是一个有界缓存的等待队列。
         基于数组的阻塞队列,同LinkedBlockingQueue类似,内部维持着一个定长数据缓冲队列(该队列由数组构成)。ArrayBlockingQueue内部还保存着两个整形变量,分别标识着队列的头部和尾部在数组中的位置。
         ArrayBlockingQueue在生产者放入数据和消费者获取数据,都是共用同一个锁对象,由此也意味着两者无法真正并行运行,这点尤其不同于LinkedBlockingQueue;按照实现原理来分析,ArrayBlockingQueue完全可以采用分离锁,从而实现生产者和消费者操作的完全并行运行。Doug Lea之所以没这样去做,也许是因为ArrayBlockingQueue的数据写入和获取操作已经足够轻巧,以至于引入独立的锁机制,除了给代码带来额外的复杂性外,其在性能上完全占不到任何便宜。 ArrayBlockingQueue和LinkedBlockingQueue间还有一个明显的不同之处在于,前者在插入或删除元素时不会产生或销毁任何额外的对象实例,而后者则会生成一个额外的Node对象。这在长时间内需要高效并发地处理大批量数据的系统中,其对于GC的影响还是存在一定的区别。

         ArrayBlockingQueue和LinkedBlockingQueue是两个最普通、最常用的阻塞队列,一般情况下,处理多线程间的生产者消费者问题,使用这两个类足以。



Java并发编程与技术内幕:ArrayBlockingQueue、LinkedBlockingQueue及SynchronousQueue源码解析

本文主要讲了Java中BlockingQueue的源码一、BlockingQueue介绍与常用方法BlockingQueue是一个阻塞队列。在高并发场景是用得非常多的,在线程池中。如果运行线程数目大于...
  • Evankaka
  • Evankaka
  • 2016年06月21日 09:18
  • 4946

SynchronousQueue,LinkedBlockingQueue,ArrayListBlockingQueue比较

SynchronousQueue         SynchronousQueue是无界的,是一种无缓冲的等待队列,但是由于该Queue本身的特性,在某次添加元素后必须等待其他线程取走后才能继续...
  • shenxm1966
  • shenxm1966
  • 2016年12月29日 19:09
  • 557

JDK容器与并发—Queue—LinkedBlockingQueue

概述       基于单链表的有界或无界阻塞队列。 1)FIFO; 2)可用带容量参数的构造函数设置队列的容量,否则为Integer.MAX_VALUE; 3)在大部分并发场景中,基于链表的队列比基...
  • Architect0719
  • Architect0719
  • 2016年04月20日 17:43
  • 460

并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue使用场景总结

LinkedBlockingQueue 发送消息队列(有消息就发送,无消息阻塞) ConcurrentLinkedQueue 读取消息队列(无消息break)? 适用阻塞队列的好处:多线程操作共同的队...
  • jiangguilong2000
  • jiangguilong2000
  • 2013年09月12日 20:23
  • 5911

JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue

目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlockingQueue,以便日后灵活使用。 1. 在Java的Concurrent包中,添加了阻塞队列Bloc...
  • xin_jmail
  • xin_jmail
  • 2014年05月19日 10:51
  • 22277

生产者消费者模型(二)-引入ArrayBlockingQueue

在《生产者消费者模型你知道多少》中简单的模拟了一个生产者消费者模型。有些网友对我的实现提出了很多质疑。我在文章的结尾也对抛出了一个问题。在代码中也充斥了大量的锁,可能有些锁是不需要的。在今天我将引入A...
  • luohuacanyue
  • luohuacanyue
  • 2013年11月18日 08:00
  • 19069

LinkedBlockingQueue 与ConcurrentLinkedQueue队列的不同与同

LinkedBlockingQueue 的API中,从队列中获取元素,有以下几个方法: 1、take():原文:Retrieves and removes the head of this queu...
  • Tardis1
  • Tardis1
  • 2016年06月20日 10:25
  • 2849

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

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ...
  • z69183787
  • z69183787
  • 2015年09月01日 10:49
  • 1132

ArrayBlockingQueue详解

1.介绍 ArrayBlockingQueue是一个阻塞式的队列,继承自AbstractBlockingQueue,间接的实现了Queue接口和Collection接口。底层以数组的形式保存数据(实...
  • qq_23359777
  • qq_23359777
  • 2017年04月12日 20:00
  • 752

ArrayBlockingQueue和LinkedBlockingQueue的区别及使用

BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会...
  • USTC_Zn
  • USTC_Zn
  • 2017年02月04日 16:56
  • 1902
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:简析SynchronousQueue,LinkedBlockingQueue,ArrayBlockingQueue
举报原因:
原因补充:

(最多只允许输入30个字)