阻塞队列,四组方法 || 同步队列

阻塞队列,四组方法 || 同步队列
阻塞队列,四组方法 || 同步队列

BlockingQueue方法有四种形式,具有不同的操作方式,不能立即满足,但可能在将来的某个时间点满足:
一个抛出异常,
第二个返回一个特殊值(空了,继续取值,返回 null 或 满了,继续添加,返回false ;没满返回true,具体取决于操作),
第三个程序将无限期地阻止当前线程,直到操作成功为止,
第四个程序块在放弃之前只有给定的最大时限。
阻塞队列,四组方法 || 同步队列

代码测试

    public static void main(String[] args) throws InterruptedException {
        test2();
    }

    // 1. 抛出异常  add || remove || 检测队首元素element
    public static void test1() {
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        // 添加元素
        blockingQueue.add("a");
        blockingQueue.add("b");
        blockingQueue.add("c");
        // 继续添加,超出容量,报异常 -> java.lang.IllegalStateException
        // blockingQueue.add("d");
        // 取出元素
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        // 继续取,此时没有元素,报异常 -> java.util.NoSuchElementException
        // System.out.println(blockingQueue.remove());

    }

    // 2. 添加元素,返回true,满了,返回false
    //    移除元素,若为空,则返回null
    // offer || poll || 检测队首元素peek
    public static void test2() {
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        // 添加元素,成功返回true
        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        // 继续添加,超出容量,返回false
        System.out.println(blockingQueue.offer("d"));
        // 取出元素
        System.out.println(blockingQueue.poll());
        // 测试队头元素,取出一个,此时为b
        System.out.println(blockingQueue.peek());
        
        System.out.println(blockingQueue.poll());
        // 测试队头元素,取出一个,此时为c
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.peek());
        // 继续取,此时没有元素,返回null
        System.out.println(blockingQueue.poll());

    }

    // 3. 添加元素,满,则阻塞等待, 一直等待
    //    移除元素,空,则阻塞等待, 一直等待
    // put || take
    public static void test3() throws InterruptedException {
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        // 添加元素
        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        // 继续添加,超出容量,阻塞
        // blockingQueue.put("d");
        // 取出元素
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());

        // 继续取,此时没有元素,阻塞
        System.out.println(blockingQueue.take());
    }

    // 4. 添加元素,返回true,满了,超时等待
    //    移除元素,若为空,超时等待
    // offer || poll 此两个的重载方法
    public static void test4() throws InterruptedException {
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        // 添加元素,成功返回true
        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        // 等待2s,返回false
        System.out.println(blockingQueue.offer("d", 2, TimeUnit.SECONDS));
        // 取出元素
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        // 继续取,此时没有元素,等待2s,返回null
        System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));

    }
}

同步队列

同步队列没有任何内部容量,甚至没有一个容量。 你不能peek在同步队列,因为一个元素,当您尝试删除它才存在; 您无法插入元素(使用任何方法),除非另有线程正在尝试删除它; 你不能迭代,因为没有什么可以迭代。 队列的头部是第一个排队的插入线程尝试添加到队列中的元素; 如果没有这样排队的线程,那么没有元素可用于删除,并且poll()将返回null 。

演示

// 同步队列,等待取的时候,才往里面添加元素
public class SynchronousQueueTest {
    public static void main(String[] args) {
        // BlockingQueue是SynchronousQueue的父亲
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
        // 开启线程,放入元素
        new Thread(() -> {
            try {
                System.out.println("开始放入aaa");
                // 执行到put方法时,只有当有其他线程尝试取出元素时,才会继续执行此方法
                blockingQueue.put("aaa");
                System.out.println("放入aaa完成");
                System.out.println("开始放入bbb");
                blockingQueue.put("bbb");
                System.out.println("放入bbb完成");
                System.out.println("开始放入ccc");
                blockingQueue.put("ccc");
                System.out.println("放入ccc完成");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 开启线程取出元素
        new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(15);
                System.out.println("尝试取出");
                String take = blockingQueue.take();
                System.out.println("取出"+take+"完成");
                TimeUnit.SECONDS.sleep(15);
                System.out.println("尝试取出");
                String take1 = blockingQueue.take();
                System.out.println("取出"+take1+"完成");
                TimeUnit.SECONDS.sleep(15);
                System.out.println("尝试取出");
                String take2 = blockingQueue.take();
                System.out.println("取出"+take2+"完成");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

上一篇:Java的优先队列:PriorityQueue


下一篇:hdu-2063 过山车(二分图)