blocking queue有三种加入队列的方法,分别为add(), put(), offer(),那么这三个方法有什么区别,我们可以写一段代码来验证一下
public static void main(String[] args) throws InterruptedException {
LinkedBlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>(1);
linkedBlockingQueue.add("1");
try {
linkedBlockingQueue.add("test add");
} catch (Exception e) {
System.out.println("------------------------");
System.out.println("test add method: ");
e.printStackTrace();
System.out.println("------------------------");
}
boolean offer = linkedBlockingQueue.offer("test offer");
System.out.println("test offer method: ");
System.out.println(offer);
System.out.println("------------------------");
System.out.println("test put method: ");
System.out.println("start: " + new Date());
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(() -> {
try {
Thread.sleep(1000);
linkedBlockingQueue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
linkedBlockingQueue.put("test put");
System.out.println("end: " + new Date());
System.out.println("------------------------");
}
结果如下:
------------------------
test add method:
java.lang.IllegalStateException: Queue full
at java.util.AbstractQueue.add(AbstractQueue.java:98)
at com.main.MainTest.main(MainTest.java:15)
------------------------
test offer method:
false
------------------------
test put method:
start: Mon Jun 22 19:05:14 CST 2020
end: Mon Jun 22 19:05:15 CST 2020
------------------------
代码模拟的是队列总大小为1的情况,并且队列里已经有一个数据,此时往里面添加元素。从结果可以看出,使用add方法时如果队列已满,会直接抛异常,不会阻塞,而且从jdk源码可以看出来add方法底层实际上调用了offer方法,使用offer方法时,队列满时会返回false,offer还有一个带时间的方法,可以等待一定时间再添加元素,可以认为不是阻塞的,put方法添加元素时从结果时间上可以看出是有阻塞的,可以调大睡眠时间,观察的直观。
所以最终add()和offer()方法不会阻塞,put方法会阻塞
从队列里面删除元素同样有两种方法,poll()和take(),poll不会阻塞,如果没有拿到就返回null,take方法会阻塞直到有数据返回