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

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、阻塞优先级队列