JUC:9阻塞队列:BlockingQueue与Collection类图关系、队列的特点及什么情况会阻塞、BlockingQueue四组必会API
- 队列的特点及什么情况会阻塞
- BlockingQueue
- BlockingQueue、BlockingDeque阻塞队列与Collection类图关系
- 什么时候会用到阻塞队列?
- BlockingQueue四组必会API
- Demo
队列的特点及什么情况会阻塞
队列的特点:先进先出FIFO(first in first out)
队列什么情况下会阻塞?
写入:如果队列满了,就必须阻塞等待
读取:队列为空,就必须阻塞等待写入
BlockingQueue
BlockingQueue、BlockingDeque阻塞队列与Collection类图关系
Deque:双端队列
AbstractQueue:非阻塞队列
SynchronousQueue:同步队列
什么时候会用到阻塞队列?
多线程并发处理,线程池,需要用一个队列去维护它的大小。
BlockingQueue四组必会API
- 抛出异常
- 有返回值,不抛出异常
- 阻塞等待,一直阻塞着
- 超时退出,超时就不等了
操作方式 | 抛出异常 | 有返回值,不抛出异常 | 阻塞等待 | 超时退出 |
---|---|---|---|---|
添加 | ![]() | ![]() | ![]() | ![]() |
移除 | ![]() | ![]() | ![]() | ![]() |
检测队首元素 | element() | peek() | 阻塞等待 | 超时等待 |
Demo
package juc.queue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.concurrent.*;
/**
* BlockingQueue四组必会API
* <p>
* 1. 抛出异常
* 2. 有返回值,不抛出异常
* 3. 阻塞等待,一直阻塞着
* 4. 超时退出,超时就不等了
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
// test1_add();
// test1_remove();
// test2_add();
// test2_remove();
// test3_add();
// test3_remove();
// test4_add();
test4_remove();
}
/**
* 1——1. 抛出异常:添加
*/
public static void test1_add() {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
blockingQueue.add("d");
/**
* 结果输出:Queue full,队列已满
* Exception in thread "main" java.lang.IllegalStateException: Queue full
* at java.util.AbstractQueue.add(AbstractQueue.java:98)
* at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
* at juc.queue.Test.test1(Test.java:36)
* at juc.queue.Test.main(Test.java:23)
*/
}
/**
* 1——2. 抛出异常:移除
*/
public static void test1_remove() {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
/*队列特性,先进先出,因此移除顺序也是a,b,c*/
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
/**
* 结果输出:java.util.NoSuchElementException,没有元素
a
b
c
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractQueue.remove(AbstractQueue.java:117)
at juc.queue.Test.test1_remove(Test.java:61)
at juc.queue.Test.main(Test.java:24)
*/
}
/**
* 2——1. 有返回值,不抛出异常:添加offer(),返回Boolean值
*/
public static void test2_add() {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d"));
/**
* 结果输出:返回true或false
* true
* true
* true
* false
*/
}
/**
* 2——2. 有返回值,不抛出异常:移除poll(),多删返回null
*/
public static void test2_remove() {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
/*队列特性,先进先出,因此移除顺序也是a,b,c*/
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
/**
* 结果输出:多删返回null
* a
* b
* c
* null
*/
}
/**
* 3——1. 阻塞等待,一直阻塞着:添加
*/
public static void test3_add() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.put("a");
blockingQueue.put("b");
blockingQueue.put("c");
blockingQueue.put("d");//队列没有位置,会一直阻塞
/**
* 结果输出:blockingQueue.put()是无返回值的,所以这里没输出,只会一直等待
*/
}
/**
* 3——2. 阻塞等待,一直阻塞着:移除
*/
public static void test3_remove() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
/*队列特性,先进先出,因此移除顺序也是a,b,c*/
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());
System.out.println(blockingQueue.take());//不存在这个元素,因此一直阻塞着
/**
* 结果输出:a,b,c之后,一直阻塞着
a
b
c
*/
}
/**
* 4——1. 超时退出,超时就不等了:添加
*/
public static void test4_add() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.offer("a"));
System.out.println(blockingQueue.offer("b"));
System.out.println(blockingQueue.offer("c"));
System.out.println(blockingQueue.offer("d", 2, TimeUnit.SECONDS));//超过2s就不拿了,用的较多
/**
* 结果输出:
* true
* true
* true
* false
*/
}
/**
* 4——2. 超时退出,超时就不等了:移除
*/
public static void test4_remove() throws InterruptedException {
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
blockingQueue.add("a");
blockingQueue.add("b");
blockingQueue.add("c");
/*队列特性,先进先出,因此移除顺序也是a,b,c*/
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll());
System.out.println(blockingQueue.poll(2, TimeUnit.SECONDS));//超过2s就不拿了,用的较多
/**
* 结果输出:a,b,c之后,等待2s,输出null
a
b
c
null
*/
}
}