队列(queue)是一组有序的元素,提取元素时按顺序从队头读取。队列一般按照插入元素的顺序实现,因此分成两类:先进先出(first-in, first-out,FIFO)队列和后进先出(last-in, first-out,LIFO)队列。
> LIFO 队列也叫栈(stack),Java 提供了 Stack 类,但强烈不建议使用——应该使用实现 Deque 接口的类。
队列也可以使用其他顺序:优先队列(priority queue)根据外部 Comparator 对象或 Comparable 类型元素的自然顺序排序元素。与 Set 不同的是,Queue 的实现往往允许出现重复的元素。而与 List 不同的是,Queue 接口没有定义处理任意索引位元素的方法,只有队列的头一个元素能访问。Queue 的所有实现都要具有一个固定的容量:队列已满时,不能再添加元素。类似地,队列为空时,不能再删除元素。很多基于队列的算法都会用到满和空这两个状态,所以 Queue 接口定义的方法通过返回值表明这两个状态,而不会抛出异常。具体而言,peek() 和 poll() 方法返回 null 表示队列为空。因此,多数 Queue 接口的实现不允许用 null 作元素。
阻塞式队列(blocking queue)是一种定义了阻塞式 put() 和 take() 方法的队列。put() 方法的作用是把元素添加到队列中,如果需要,这个方法会一直等待,直到队列中有存储元素的空间为止。而 take() 方法的作用是从队头移除元素,如果需要,这个方法会一直等待,直到队列中有元素可供移除为止。阻塞式队列是很多多线程算法的重要组成部分,因此 BlockingQueue 接口(扩展 Queue 接口)在 java.util.concurrent 包中定义。
队列不像集、列表和映射那么常用,只在特定的多线程编程风格中会用到。这里,我们不举实例,而是试着厘清一些令人困惑的队列插入和移除操作。