Java数据结构-Queue系列

一、什么是 queue(队列) ?

在数据结构中,队列的解释是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作。故队列又称为先进先出(FIFO——first in first out)的线性表。

二、queue 的实现和继承

Queue 和 List 、Set 一样都继承自 Collection 接口,其中我们经常用到的 LinkedList 实现了 Queue 接口。

而在并发队列上, JDK 提供了两套实现:一个就是以 ConcurrentLinkedQueue 为代表的高性能的非阻塞队列;一个是以 BlockingQueue 为代表的阻塞队列,例如:ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、DelayQueue等。这两种都实现或继承自 Queue。

Queue接口方法定义:

//添加元素,成功返回true,容量不够抛IllegalStateException 
boolean add(E e) 
//添加元素,成功返回true,容量不足返回false 
boolean offer(E e) 
//移除队首元素,队列为空时抛NoSuchElementException 
E remove() 
//移除队首元素,队列为空时返回null 
E poll() 
//查看队首元素,队列为空时抛NoSuchElementException 
E element() 
//查看队首元素,队列为空时返回null 
E peek()

非阻塞:ConcurrentLinkedQueue

ConcurrentLinkedQueue 是一个适用于高并发场景下的队列,通过无锁的方式实现了高并发状态下的高性能,通常ConcurrentLinkedQueue 的性能好于 BlockingQueue 。它是一个基于链接节点的无界线程安全队列,其中ConcurrentLinkedQueue通过 sun.misc.Unsafe 类的CAS操作来保证线程安全。该队列的元素遵循先进先出的原则,该队列不允许 null 元素,如果存入 null ,则会抛出 NullPointerException 异常。 

ConcurrentLinkedQueue 的继承关系:

ConcurrentLinkedQueue 的重要方法:

  • add()    增加一个元素   如果队列已满,则抛出一个IIIegaISlabEepeplian异常
  • offer()  同 add 方法 
  • poll()   移除并返问队列头部的元素 如果队列为空,则返回null
  • peek() 返回队列头部的元素            如果队列为空,则返回null
public class ConcurrentLinkedQueueTest {

    public static void main(String[] args) {

        ConcurrentLinkedQueue c = new ConcurrentLinkedQueue();
        c.add("a");
        c.add("b");
        c.add("c");
        c.add("d");
        c.offer("e");

        System.out.println(c.poll()); //移除并取出元素
        System.out.println(c.size());
        System.out.println(c.peek()); //只取出不移除元素
        System.out.println(c.size());
    }
}

返回结果:

a
4
b
4

Process finished with exit code 0

阻塞:BlockingQueue

BlockingQueue 的重要方法:

//添加元素,容量不足阻塞 
void put(E e) throws InterruptedException 
//添加元素,容量不足时等待指定时间 
boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException 
//移除队首元素,队列为空时阻塞 
E take() throws InterruptedException 
//移除队首元素,队列为空时等待指定时间 
E poll(long timeout, TimeUnit unit) throws InterruptedException

其中有五个阻塞队列类实现了BlockingQueue 接口。

  • ArrayBlockingQueue :一个由数组支持的有界队列。
  • LinkedBlockingQueue :一个由链接节点支持的可选有界队列。
  • PriorityBlockingQueue :一个由优先级堆支持的无界优先级队列。
  • DelayQueue :一个由优先级堆支持的、基于时间的调度队列。
  • SynchronousQueue :一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

ArrayBlockingQueue:基于数组的阻塞队列实现,在 ArrayBlockingQueue 内部,维护了一个定长数组,以便缓存队列中的数据对象,其内部没有实现读写分离,也就意味着生产和消费不能完全并行,长度是需要定义的,可以指定先进先出或者先进后出,也叫有界队列,在很多场合非常适用。

LinkedBlockingQueue :基于链表的阻塞队列,同ArrayBlockingQueue 类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),LinkedBlockingQueue  之所以能够高效的处理并发数据,是因为其内部采用分离锁(读写分离两个锁),从而实现生产者和消费者操作的完全并行运行,它是一个无界队列(指的是没有设置固定大小的队列,这些队列的特点是可以直接入列,直到溢出。)。

PriorityBlockingQueue :基于优先级的阻塞队列(优先级的判断通过构造函数传入的 Compator 对象来决定,也就是说传入队列的对象必须实现 Comparable 接口),在实现 PriorityBlockingQueue 时,内部控制线程同步的锁采用的是公平锁,它也是一个无界队列。

  • 公平锁:加锁前先查看是否有排队等待的线程,有的话优先处理排在前面的线程,先来先得
  • 非公平所:线程加锁时直接尝试获取锁,获取不到就自动到队尾等待。

DelayQueue :带有延迟时间的 Queue,其中的元素只有当其指定的延迟时间到了,才能从队列中获取到该元素。DelayQueue 中的元素必须实现 Delayed 接口, DelayQueue 是一个没有大小限制的队列,应用场景很多,比如对缓存超时数据进行移除、任务超时处理、空闲连接的关闭等等。

SynchronousQueue:一种没有缓冲的队列,生产者产生的数据直接会被消费者获取并消费。

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值