数据结构(集合)学习之Queue

集合

框架关系图:

Collection接口下面有三个子接口:List、Set、Queue。此篇是关于Queue<E>的简单学习总结。

Queue:

Queue(队列):是一种特殊的链型结构,它的特点是先进先出(FIFO),通常只在尾部插入,头部删除,它经常和Stack(栈)进行比较,但Stack的特点是先进后出。注意:队列通常但不一定是以FIFO(先进先出)方式排序元素。 除了优先级队列之外,优先级队列是根据提供的比较器对元素进行排序,还是元素的自然排序,以及对元素LIFO(先进先出)进行排序的LIFO队列(或堆栈)。 无论使用什么顺序,队列的头都是通过调用remove()或poll()删除的元素。

  • 方法摘要

    Modifier and Type 方法 描述
    boolean add?(E e)
    将指定的元素插入到此队列中,如果可以立即执行此操作而不违反容量限制, true成功返回 true ,如果当前没有可用的空间,则抛出 IllegalStateException
    E element?()
    检索,但不删除,这个队列的头。
    boolean offer?(E e)
    如果在不违反容量限制的情况下立即执行,则将指定的元素插入到此队列中。
    E peek?()
    检索但不删除此队列的头,如果此队列为空,则返回 null
    E poll?()
    检索并删除此队列的头部,如果此队列为空,则返回 null
    E remove?()
    检索并删除此队列的头。 

队列分为阻塞队列和非阻塞队列(平时常见的为非阻塞队列,例如:LinkedList)。

非阻塞队列:

在进行“当队列为空去删除队列中的数据”和“当队列已满继续往里追加数据”时不会进行阻塞,所以在开发中为了维护项目的稳定与数据安全就需要在其他逻辑中增添相应的处理方法。对于非阻塞队列,一般情况下建议使用offer、poll和peek三个方法,不建议使用add和remove方法。因为使用offer、poll和peek三个方法可以通过返回值判断操作成功与否,而使用add和remove方法却不能达到这样的效果。注意,非阻塞队列中的方法都没有进行同步措施。

阻塞队列:

和非阻塞队列不同的是,当线程在进行“当队列为空去删除队列中的数据”和“当队列已满继续往里追加数据”两种操作时,线程会被阻塞住,当队列不为空或者没有满的时候,被阻塞的线程会自动被唤醒然后进行后续的逻辑运行(其实原理是在非阻塞队列的方法中,加了“锁”(Lock),当线程可运行了再“解锁”)。

自从Java 1.5之后,在java.util.concurrent包下提供了若干个阻塞队列,主要有以下几个:

  • ArrayBlockingQueue:基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象时必须制定容量大小。并且可以指定公平性与非公平性,默认情况下为非公平的,即不保证等待时间最长的队列最优先能够访问队列。
  • LinkedBlockingQueue:基于链表实现的一个阻塞队列,在创建LinkedBlockingQueue对象时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。
  • PriorityBlockingQueue:以上2种队列都是先进先出队列,而PriorityBlockingQueue却不是,它会按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都是优先级最高的元素。注意,此阻塞队列为无界阻塞队列,即容量没有上限(通过源码就可以知道,它没有容器满的信号标志),前面2种都是有界队列。
  • DelayQueue:基于PriorityQueue,一种延时阻塞队列,DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。DelayQueue也是一个无界队列,因此往队列中插入数据的操作(生产者)永远不会被阻塞,而只有获取数据的操作(消费者)才会被阻塞。
  1     final ReentrantLock lock;
  2
  3     private final Condition notEmpty;
  4
  5     private final Condition notFull;
  6
  7     public ArrayBlockingQueue(int capacity) {
  8         this(capacity, false);
  9     }
 10
 11     public ArrayBlockingQueue(int capacity, boolean fair) {
 12         if (capacity <= 0)
 13             throw new IllegalArgumentException();
 14         this.items = new Object[capacity];
 15         lock = new ReentrantLock(fair);
 16         notEmpty = lock.newCondition();
 17         notFull =  lock.newCondition();
 18     }
 19
 20     public ArrayBlockingQueue(int capacity, boolean fair,
 21                               Collection<? extends E> c) {
 22         this(capacity, fair);
 23
 24         final ReentrantLock lock = this.lock;
 25         lock.lock(); // Lock only for visibility, not mutual exclusion
 26         try {
 27             int i = 0;
 28             try {
 29                 for (E e : c) {
 30                     checkNotNull(e);
 31                     items[i++] = e;
 32                 }
 33             } catch (ArrayIndexOutOfBoundsException ex) {
 34                 throw new IllegalArgumentException();
 35             }
 36             count = i;
 37             putIndex = (i == capacity) ? 0 : i;
 38         } finally {
 39             lock.unlock();
 40         }
 41     }
 42
 43     public boolean offer(E e) {
 44         checkNotNull(e);
 45         final ReentrantLock lock = this.lock;
 46         lock.lock();
 47         try {
 48             if (count == items.length)
 49                 return false;
 50             else {
 51                 enqueue(e);
 52                 return true;
 53             }
 54         } finally {
 55             lock.unlock();
 56         }
 57     }
 58
 59     public void put(E e) throws InterruptedException {
 60         checkNotNull(e);
 61         final ReentrantLock lock = this.lock;
 62         lock.lockInterruptibly();
 63         try {
 64             while (count == items.length)
 65                 notFull.await();
 66             enqueue(e);
 67         } finally {
 68             lock.unlock();
 69         }
 70     }
 71
 72     public E poll() {
 73         final ReentrantLock lock = this.lock;
 74         lock.lock();
 75         try {
 76             return (count == 0) ? null : dequeue();
 77         } finally {
 78             lock.unlock();
 79         }
 80     }
 81
 82     public E take() throws InterruptedException {
 83         final ReentrantLock lock = this.lock;
 84         lock.lockInterruptibly();
 85         try {
 86             while (count == 0)
 87                 notEmpty.await();
 88             return dequeue();
 89         } finally {
 90             lock.unlock();
 91         }
 92     }
 93
 94     public E poll(long timeout, TimeUnit unit) throws InterruptedException {
 95         long nanos = unit.toNanos(timeout);
 96         final ReentrantLock lock = this.lock;
 97         lock.lockInterruptibly();
 98         try {
 99             while (count == 0) {
100                 if (nanos <= 0)
101                     return null;
102                 nanos = notEmpty.awaitNanos(nanos);
103             }
104             return dequeue();
105         } finally {
106             lock.unlock();
107         }
108     }

原文地址:https://www.cnblogs.com/Bernard94/p/12322684.html

时间: 2024-10-11 06:19:59

数据结构(集合)学习之Queue的相关文章

深入Java集合学习系列:HashMap的实现原理

参考文献 引用文献:深入Java集合学习系列:HashMap的实现原理,大部分参考这篇博客,只对其中进行稍微修改 自己曾经写过的:Hashmap实现原理 1. HashMap概述: HashMap是基于哈希表的Map接口的非同步实现(Hashtable跟HashMap很像,唯一的区别是Hashtalbe中的方法是线程安全的,也就是同步的).此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 2. HashMap的数据结构: 在ja

STL学习——Stack/Queue篇

STL学习--Stack/Queue篇 Stack 概述 stack是一种先进先出的数据结构,只有一个出口,stack允许新增元素,移除元素,取得最顶端元素.但除了最顶端外,没有任何办法可以存取stack其他元素.即不允许遍历行为. 实现 stack实现是以容器为底部结构的,将容器的接口改变,使其符合"先进先出"特性,便形成了一个栈.具体实现可以将底部deque的头端开口封闭,便实现了stack.因为stack具有"修改某物接口,形成另一种风貌"性质,故称为&quo

数据结构的学习思路

数据结构课程的重要性再怎么强调也不为过,对于将来从事编程工作的程序员来说,这是必修的内功心法,程序员的内功高低就体现在这个上面.当然对于非计算机从业人员,掌握这门课程对于锻炼我们的数学思维.逻辑思维和理性思维来说也是有百益而无一害的.现在课程视频已经全部上传到51CTO学院了,为了让大家更好的学习这套教学视频,我把课程的学习思路整理到下面,希望对大家有所帮助. 一.课程层次 从低到高分三个层面:实现(数据结构).使用(数据结构)和(算法)分析.课程的重点放在实现和使用上,分析做为后续课程的重点,

java集合学习一

1.Set存放的元素是无序的不可重复. 2.List存放的元素为有序可重复. 3.重写equals方法,一般最好重写hasCode方法,当对象作为key的时候及索引,会使用hasCode方法进行查找. 4.容器对象在调用remove,contains等方法时需要比较对象是否相等,这会涉及到对象类型的equals方法和 hashCode方法.对于自定义的类型,需要重写equals和hashCode方法以实现自定义的对象相等规则.相等的对象 应该具有相等的hashCode. 5.ArrayList底

《大话数据结构》学习笔记 排序

排序的严格定义:  假设含有n个记录的序列为{r1,r2,......,rn},对应的关键字分别为{k1,k2......,kn},需确定1,2,......,n的一种排列p1,p2,......,pn,使其相应的关键字 满足Kp1<=Kp2<=......Kpn关系,即使得序列成为一个按关键字有序的序列(rpq,rp2,......rpn),此操作称为排序.  排序的稳定性:内排序与外排序(根据记录是否全部放置在内存中). 根据排序中的主要操作,可以分为插入排序类(直接插入排序->希尔

深入Java集合学习系列:LinkedHashMap的实现原理

1. LinkedHashMap概述: LinkedHashMap是Map接口的哈希表和链接列表实现,具有可预知的迭代顺序.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变.   LinkedHashMap实现与HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表.此链接列表定义了迭代顺序,该迭代顺序可以是插入顺序或者是访问顺序.   注意,此实现不是同步的.如果多个线程同时访问链接的哈希映射,而其中至少一个线

转:深入Java集合学习系列:HashSet的实现原理

0.参考文献 深入Java集合学习系列:HashSet的实现原理 1.HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持.它不保证set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用null元素.HashSet中不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT

《数据结构》学习-- Hash(2) --Separate Chaining

回顾 Separate Chaining简介 Rehash Separate Chaining实现 1 Hash表主体 2 初始化操作 3 Hash Function 4 Find 5 Insert 6 Remove 7 rehash 8 nextPrime HashTable测试 1正确性测试 2 性能测试 总结 本系列是<数据结构与算法分析-C语言描述>(Data Structures and Algorithm Analysis in C,作者Mark Weiss)一书的学习笔记,当我在

集合( Stack / Queue / Hashtable 都没有索引)

/*   // 集合     Stack         没有索引!"好比是死胡同"   Stack s=new Stack ();       //特殊集合  堆!先进后出,后进先出!   s.Push("1");                //赋值内容  要用     “”   s.Push("2"); s.Push("3"); s.Push("4"); s.Push("5");