0%

队列(queue)

各种队列介绍

1
2
3
4
5
6
7
ArrayBlockingQueue 由数组结构组成的有界阻塞队列
LinkedBlockingQueue 由链表结构组成的有界(但大小默认值为Integer.MAX_VALUE 21亿)阻塞队列
PriorityBlockingQueue 支持优先级排序的无界阻塞队列
DelayQueue 使用时间优先级队列实现的延迟无界阻塞队列
SynchronousQueue 不存储、匀速的阻塞队列,容量为零的队列(用于一个线程给另一个线程下达任务)
LinkedTransferQueue 由链表结构组成的无界阻塞队列 transfer将元素放入队列之后会阻塞,等待元素被拿走
LinkedBlockingDeque 由链表结构组成的双向阻塞队列

BlockingQueue接口

操作失败会抛出异常的方法(add、remove、element)

1
2
3
4
5
boolean add(E e):添加元素,当阻塞队列满的时候再进行add会抛Exception in thread "main" java.lang.IllegalStateException: Queue full

E remove():移除值并返回,当阻塞队列空的时候再进行remove会抛 Exception in thread "main" java.util.NoSuchElementException

E element():获取队列排头的元素,没有值时Exception in thread "main" java.util.NoSuchElementException

操作失败返回false null的方法(offer、poll、peek)

1
2
3
4
5
6
7
boolean offer(E e):当阻塞队列满的时候再进行offer会返回false

boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException:当阻塞队列满的时候再进行offer时,会阻塞2S,仍然阻塞则会返回false

E poll():移除值并返回,当阻塞队列空的时候再进行poll会返回null

E peek():获取队列排头的元素,没有值时为null

一直阻塞的方法(put、take)

1
2
3
void put(E e) throws InterruptedException:当阻塞队列满的时候会一直阻塞直到put数据或响应中断

E take() throws InterruptedException:当阻塞队列空的时候会一直阻塞直到take数据或响应中断

以ArrayBlockingQueue为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
public class BlockIngQueueDemo {
public static void main(String[] args) throws InterruptedException {
//阻塞队列,先进先出
BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

//会抛异常的方法:add、element、remove
exceptionBlockQueue(blockingQueue);
//会阻塞的方法:put、take
block(blockingQueue);
//返回true、false、null的方法:offer、peek、poll
booleanBlockQueue(blockingQueue);
//超时返回true、false的方法:offer
timeout(blockingQueue);
}

/**
* 操作d失败等待超时返回false null
*/
private static void timeout(BlockingQueue<String> blockingQueue) throws InterruptedException {
System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));//true
System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));//true
System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));//true
//当阻塞队列满的时候再进行offer时,会阻塞2S,仍然阻塞则会返回false
System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));//false
}

/**
* 一直阻塞
*/
private static void block(BlockingQueue<String> blockingQueue) throws InterruptedException {
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
//当阻塞队列满的时候会一直阻塞直到put数据或响应中断
//blockingQueue.put("d");
//获取并移除队列的值
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
//当阻塞队列空的时候会一直阻塞直到take数据或响应中断
//System.out.println(blockingQueue.take());
}

/**
* 操作失败返回false null
*/
private static void booleanBlockQueue(BlockingQueue<String> blockingQueue) {
System.out.println(blockingQueue.offer("a")); //true
System.out.println(blockingQueue.offer("b")); //true
System.out.println(blockingQueue.offer("c")); //true
//当阻塞队列满的时候再进行offer会返回false
System.out.println(blockingQueue.offer("d")); //false

//获取队列排头的元素,没有值时为null
System.out.println(blockingQueue.peek());//a

//移除值并返回,当阻塞队列空的时候再进行poll会返回null
System.out.println(blockingQueue.poll());//a
System.out.println(blockingQueue.poll());//b
System.out.println(blockingQueue.poll());//c
System.out.println(blockingQueue.poll());//null
}

/**
* 操作失败会抛出异常
*/
private static void exceptionBlockQueue(BlockingQueue<String> blockingQueue) {
//######### 抛异常方法 ###########
//添加
System.out.println(blockingQueue.add("a"));//true
System.out.println(blockingQueue.add("b"));//true
System.out.println(blockingQueue.add("c"));//true
//当阻塞队列满的时候再进行add会抛Exception in thread "main" java.lang.IllegalStateException: Queue full
System.out.println(blockingQueue.add("c"));//Exception in thread "main" java.lang.IllegalStateException: Queue full

//获取队列排头的元素,没有值时Exception in thread "main" java.util.NoSuchElementException
System.out.println(blockingQueue.element());//a

//移除值并返回,当阻塞队列空的时候再进行remove会抛 Exception in thread "main" java.util.NoSuchElementException
System.out.println(blockingQueue.remove());//a
System.out.println(blockingQueue.remove());//b
System.out.println(blockingQueue.remove());//c
System.out.println(blockingQueue.remove());// Exception in thread "main" java.util.NoSuchElementException
}
}