BlockingQueue
API文档中的描述
BlockingQueue与Collection的关系
四组API
方式 | 抛出异常 | 有返回值,不抛异常 | 阻塞 等待 | 超时等待 |
---|---|---|---|---|
添加 | add() | offer() | put() | offer(,) |
移除 | remove() | poll() | take() | poll(,) |
检测队首元素 | element() | peek() |
添加:
add()只能添加队列的容量大小的元素,如果添加元素数量超过队列容量大小,则会IllegalStateException: Queue full 抛出异常!
public class BlockingQueue {
public static void main(String[] args) throws InterruptedException {
test();
}
/**
* 抛出异常
*/
public static void test(){
// 队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
System.out.println(blockingQueue.add("d"));
}
}
offer()如果添加到队列的元素数量超过队列容量大小,不会像add()那样抛出异常,而是返回bool值false。
put()如果添加到队列的元素数量超过队列容量大小,则会处于等待状态,出现队列阻塞。
offer(,)如果添加到队列的元素数量超过队列容量大小,则会出现等待,当等待时间超过我们设定时间就会退出,代码如下。
blockingQueue.offer("d",2,TimeUnit.SECONDS); // 等待超过2秒就退出
移除:
remove():队列中有多少个元素就只能移除多少个,最多只能移除的次数为队列容量大小,即队满的情况,否则会抛出异常 java.util.NoSuchElementException。
public class BlockingQueue {
public static void main(String[] args) throws InterruptedException {
test();
}
/**
* 抛出异常
*/
public static void test(){
// 队列的大小
ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);
System.out.println(blockingQueue.add("a"));
System.out.println(blockingQueue.add("b"));
System.out.println(blockingQueue.add("c"));
System.out.println("============");
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
System.out.println(blockingQueue.remove());
}
}
poll():当执行pull()次数超过队列容量大小时,不会像remove那样抛出异常而是返回null。
take():当执行take()次数超过队列容量大小时,会出现队列阻塞。
poll(,,)如果执行poll(,)次数超过队列容量大小,则会出现等待,当等待时间超过我们设定时间就会退出,代码如下。
blockingQueue.poll(2, TimeUnit.SECONDS); // 等待超过2秒就退出
element(),peek():用于查看队首元素,在队列元素为空的情况下,element() 方法会抛出NoSuchElementException异常,peek() 方法只会返回 null。
SynchronizeQueue
同步队列跟阻塞队列不一样的地方在于它不存储元素如果往里面put了一个元素,必须从里面先take取出来,否则不能在put进去!
代码演示:
public class SynchronizeQueueDemo {
public static void main(String[] args) {
BlockingQueue<String> blockingQueue = new SynchronousQueue<>(); // 同步队列
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " put 1");
blockingQueue.put("1");
System.out.println(Thread.currentThread().getName() + " put 2");
blockingQueue.put("2");
System.out.println(Thread.currentThread().getName() + " put 3");
blockingQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "T1").start();
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + " take " + blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + " take " + blockingQueue.take());
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName() + " take " + blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "T2").start();
}
}
声明:本笔记是学习狂神juc课程所做的笔记,图2来自视频的截图,大家可以点击链接观看并三连予以支持。
https://www.bilibili.com/video/BV1B7411L7tE?p=21