天天看点

Blocking Queue三种加入队列方法对比

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方法会阻塞直到有数据返回