队列是咱们学java必须接触到的知识,不少内容都和它相关,可是你真的了解它们的概念和使用方法吗?在本文,你能够获取关于queue的一切信息,但愿我可以帮助你在java的学习道路上乘风破浪。
概念
队列
队列是一种特殊的线性表,是一种先进先出(FIFO)的数据结构。它只容许在表的前端(front)进行删除操做,而在表的后端(rear)进行插入操做。进行插入操做的端称为队尾,进行删除操做的端称为队头。队列中没有元素时,称为空队列。正由于队列先进先出的先天特性,在一些特殊场合下称为首选项,好比:电商的秒杀。将每个订单请求做为一个处理任务,按顺序一一排列到队列中等待处理。经典运用:线程池。
java 中的队列(Queue)
Queue接口与List、Set为同级别,都为Collection接口子接口。除了拥有 Collection 接口基本操做外,队列还提供其余的插入、提取和检查操做。每一个方法都存在两种形式:一种抛出异常(操做失败时),另外一种返回一个特殊值(null 或 false,具体取决于操做)。插入操做的后一种形式是用于专门为有容量限制的 Queue 实现设计的;在大多数实现中,插入操做不会失败。前端
方法对比
分类
Queue 大致分2类:
1>非阻塞队列: 没有实现BlockingQueue接口的队列:
常见的有:
ConcurrentLinkedQueue:一个基于链表节点的***线程安全队列。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列获取操做从队列头部得到元素。当多个线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。
LinkedList:底层维护一个链表,实现全部可选的列表操做,而且容许全部元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。可用于实现堆栈、队列或双端队列等。
PriorityQueue:一个基于优先级堆的***优先级队列。优先级队列的元素按照其天然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。
2>阻塞队列:实现BlockingQueue接口的队列
常见有:
ArrayBlockingQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操做则是从队列头部开始得到元素。由于底层缓存的一有界的数组,当缓存区建立成功后,长度便固定,试图向满队列中放元素,势必致使阻塞。另外,此类也支持公平原则,若是公平参数被设置true,等待时间最长的线程会优先获得处理。公平性一般会下降吞吐量,但也减小了可变性和避免了“不平衡性”。
LinkedBlockingQueue:底层使用链表实现的无上界的阻塞队列(可使用指定界限的方式,设置队列的容量大小, 默认为 Integer.MAX_VALUE。),一般链表队列的的吞吐量要高于基于数组的队列,可是在大多数并发应用程序中,其可预知的性能要低。
DelayQueue:一个***阻塞队列,和其余队列不一样,获取该队列数据,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。若是延迟都尚未期满,则队列没有头部,而且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于等于 0 的值时,将发生到期。即便没法使用 take 或 poll 移除未到期的元素,也不会将这些元素做为正常元素对待。
PriorityBlockingQueue:是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList同样,因此在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是***的,可是因为资源被耗尽,因此试图执行添加操做可能会致使 OutOfMemoryError),可是若是队列为空,那么取元素的操做take就会阻塞,因此它的检索操做take是受阻的。另外,往入该队列中的元 素要具备比较能力。
SynchronousQueue:一种阻塞队列,其中每一个插入操做必须等待另外一个线程的对应移除操做 ,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。不能在同步队列上进行 peek,由于仅在试图要移除元素时,该元素才存在;除非另外一个线程试图移除某个元素,不然也不能(使用任何方法)插入元素;也不能迭代队列,由于其中没有元素可用于迭代。队列的头 是尝试添加到队列中的首个已排队插入线程的元素;若是没有这样的已排队线程,则没有可用于移除的元素而且 poll() 将会返回 null。对于其余 Collection 方法(例如 contains),SynchronousQueue 做为一个空 collection。此队列不容许 null 元素。java
看完这些或许你已经对queue有必定了解了,但这还只是一些基础的概念和内容,接下来,我将分享更多关于queue使用方法相关的问题。但愿你继续关注我,我会帮助你在java的道路上更进一步。后端