梦想还是要有的,万一忘了咋办?

0%

Java队列

目录

  • 类图
  • 接口方法介绍
  • 实现类及使用方法
  • 各队列是有界还是无界的

接口

接口 名称 描述
Queue 队列 支持头部,插入、删除、检查
Deque 双向队列 支持队列、栈(push\pop\peek)
BlockingQueue 阻塞队列 插入删除支持永久阻塞put/take,定时阻塞offer(e,time,unit)\poll(time,unit)
BlockingDeque 阻塞双向队列 Deque基础上增加阻塞函数
TransferQueue 传输队列 生产者会阻塞到元素被消费为止

Queue接口

每种操作都提供两个方法,一个方法抛出异常、一个方法返回特殊值。

类型 抛出异常 返回特殊值 描述
插入 add(e) offer(e) 插入数据
删除 remove() poll() 删除且返回顶部元素
检查 element() peek() 返回顶部元素,但不删除

Deque接口

Deque 是 “double ended queue”缩写

deque接口方法

Deque继承了Queue接口,Deque同时具备Queue的接口的方法

BlockingQueue接口

类型 异常 特殊返回值 阻塞 超时
插入 add offer put offer(e,time,unit)
删除 remove poll take poll(time,unit)
检查 element peek – –

BlockingDeque接口包含

操作头元素

类型 异常 特殊返回值 阻塞 超时
插入 addFirst offerFirst putFirst offerFirst(e,time,unit)
删除 removeFirst pollFirst takeFirst pollFirst(time,unit)
检查 getFirst peekFirst – –

操作尾元素

类型 异常 特殊返回值 阻塞 超时
插入 addLast offerLast putLast offerLast(e,time,unit)
删除 removeLast pollLast takeLast pollLast(time,unit)
检查 getLast peekLast – –

Queue & Deque

类型 Queue Deque
插入 add addLast
… offer offerLast
… put putLast
… offer(e,time,unit) offerLast(e,time,unit)
删除 remove removeFirst
… poll pollFirst
… take takeFirst
… poll(time,unit) pollFirst(time,unit)
检查 element getFirst
… peek peekFirst

TransferQueue

  • 继承BlockingQueue接口
新增方法 描述
tryTransfer(e) 将e传输给消费者,返回结果
transfer(e) 同上,抛出异常
tryTransfer(e,time,unit) 超时前传递给消费者(调用take\poll),返回成功、失败

常见实现类

LinkedList

  • 双向链表实现
  • 元素时有序的,输出顺序与输入顺序一致
  • 允许元素为 null
  • 所有指定位置的操作都是从头开始遍历进行的
  • 和 ArrayList 一样,不是同步容器
  • 先进先出

实现Deque、List接口

1
2
3
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable

PriorityQueue

  • 优先级队列
  • 堆(默认是小顶堆)
1
2
3
4
5
6
//默认
new PriorityQueue<>();
//大顶堆
new PriorityQueue<>((x, y) -> (y - x));
//阻塞
new PriorityBlockingQueue<>();

AsLIFOQueue

  • 后进先出队列
1
2
3
//参数必须实现Deque
Collections.asLifoQueue(Deque deque);
Collections.asLifoQueue(new LinkedList<>());

DelayQueue

  • 依赖 PriorityQueue 实现
  • 一个无界的BlockingQueue
  • 放置实现了Delayed接口的对象
  • 对象只能在其到期时才能从队列中取走
  • 不支持null

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E> {...}

public class DelayTask implements Delayed{
//将自己的时间单位转换为目标的时间单位
@Override
public long getDelay(TimeUnit unit) {
return unit.convert((time.getTime() - System.currentTimeMillis()), TimeUnit.MILLISECONDS);
}
//决定大顶堆、小顶堆
//延迟任务执行,按照倒计时时间排序时必须是小顶堆
@Override
public int compareTo(Delayed o) {
long s = this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS);
return (int) s;
}
}

LinkedBlockingQueue

  • 阻塞队列
1
2
3
4
5
6
7
8
9
10
11
12
BlockingQueue<Integer> q = new LinkedBlockingQueue<>(1);
//==========删除
//进入阻塞状态
//q.take();
//阻塞10秒
//q.poll(10, TimeUnit.SECONDS);
//========增加
//阻塞
q.put(1);
//q.put(2);
//阻塞10秒
q.offer(2, 10, TimeUnit.SECONDS);

SynchronousQueue

  • 轻量级容器
  • 公平模式,TransferQueue实现
  • 非公平模式,TransferStack 实现
  • 执行take操作后阻塞消失,只能确保数据传输成功、并不能保证业务处理成功

线程池使用案例:

  • 创建指定数量的线程池使用:LinkedBlockingQueue
  • 创建非固定数量的线程池使用:SynchronousQueue
1
2
3
4
5
6
7
8
9
10
11
12
13
//固定数量线程池
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
//非固定数量线程池
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}

TransferQueue

  • 按需生产

源代码

1
2
public interface TransferQueue<E> extends BlockingQueue<E> {}

其他

  • ArrayBlockingQueue、有界队列
  • PriorityBlockingQueue、阻塞优先级队列