阻塞队列,同步队列
# 1. 阻塞对列
BlockingQueue方法有四种形式,具有不同的操作方式,不能立即满足,但可能在将来的某个时间点满足:
- 一个抛出异常
- 第二个返回一个特殊值(
null
或false
,具体取决于操作) - 第三个程序将无限期地阻止当前线程,直到操作成功为止
- 第四个程序块在放弃之前只有给定的最大时限。
这些方法总结在下表中:
方式 | ArrayBlockingQueue抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add() | offer() | put() | offer(元素,等待时长,时间单位 ) |
移除 | remove() | poll() | take() | poll(等待时长,时间单位 ) |
检测队首元素 | element() | peek() | ———— | ——— |
抛出异常
- 当队列已满时,
add
添加元素抛出异常:IllegalStateException: Queue full
(对列已满) - 当队列为空时,
remove
移除元素抛出异常:NoSuchElementException
(对列为空) - 当队列为空时,
element
查看队首元素时抛出:NoSuchElementException
有返回值,不抛出异常
- 当队列已满时,
offer
添加元素为false - 当队列为空时,
poll
移除元素为false - 当队列为空时,
peek
查看队首元素为null
阻塞等待
- 当队列已满时,
put
添加元素,队列处于阻塞等待中 - 当队列为空时,
take
移除元素,队列处于阻塞等待中
超时等待
- 当队列已满时,
offer(重载)
添加元素为,超时退出 - 当队列为空时,
poll(重载)
移除元素为,超时退出
# 2. 同步队列
BlockingQueue中每个插入操作必须等待另一个线程相应的删除操作,反之亦然。 同步队列没有任何内部容量,甚至没有一个容量。 你不能peek
在同步队列,因为一个元素,当您尝试删除它才存在; 您无法插入元素(使用任何方法),除非另有线程正在尝试删除它; 你不能迭代,因为没有什么可以迭代。 队列的头部是第一个排队的插入线程尝试添加到队列中的元素; 如果没有这样排队的线程,那么没有元素可用于删除,并且poll()
将返回null
。 为了其他Collection
方法(例如contains
)的目的, SynchronousQueue
充当空集合。 此队列不允许null
元素。
SynchronousQueue
没有容量,只能是将存入的取出才能继续存入(理解为容量为1)
public class SynchronousQueueTest {
public static void main(String[] args) {
BlockingQueue<String> queue = new SynchronousQueue<> ();
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + "放入元素" + "1");
queue.put("1");
System.out.println(Thread.currentThread().getName() + "放入元素" + "2");
queue.put("2");
System.out.println(Thread.currentThread().getName() + "放入元素" + "3");
queue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "-->>" + queue.take());
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "-->>" + queue.take());
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "-->>" + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程2").start();
}
}
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
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
编辑 (opens new window)
上次更新: 2021/06/27, 10:49:09