BlockingQueue阻塞队列

BlockingQueue阻塞队列:在队列为空时,获取元素的线程会等待队列变为非空。当队列满时,存储元素的线程会等待队列可用。阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素

队列FIFO先进先出 一端写入一端取出

写入如果队列满了就必须阻塞等待,如果队列是空的必须阻塞等待生产

注意:BlockingQueue不接受null值,试图添加一个null元素时会抛出异常。BlockingQueue 可以是限定容量的 超过给定容量时是无法添加的

BlockingQueue的四种API

ArrayBolckingQueue:基于数组的有界阻塞队列

阻塞队列核心方法

方法类型抛出异常特殊值( 有返回值)阻塞超时
插入addofferputoffer
移除removepolltakepoll
判断队列首elementpeek--

ArrayBolckingQueue使用示例:

第一组会抛出异常API演示

public static void test(){
        //自定义数组队列的数量
        ArrayBlockingQueue blockingDeque=new ArrayBlockingQueue<>(3);
        //add添加成功返回true
        System.out.println(blockingDeque.add("a"));
        System.out.println(blockingDeque.add("b"));
        System.out.println(blockingDeque.add("c"));
        //取队列首元素
        System.out.println(blockingDeque.element());
        //超过队列大小 add会抛出异常  Queue full
//        System.out.println(blockingDeque.add("d"));
        System.out.println("===============================");
        //remove取出一个元素  返回取出的值   如果队列为空  remove会抛出异常
        System.out.println(blockingDeque.remove());
        System.out.println(blockingDeque.remove());
        System.out.println(blockingDeque.remove());
    }

第二组特殊值( 有返回值)API使用

/**
 * 返回值
 */
public static void test1(){
    //自定义数组队列的数量
    ArrayBlockingQueue blockingDeque=new ArrayBlockingQueue<>(3);
    //offer添加元素,如果添加成功会返回true
    System.out.println(blockingDeque.offer("a"));
    System.out.println(blockingDeque.offer("b"));
    System.out.println(blockingDeque.offer("c"));
    //当越界时添加元素,会返回false,不会抛出异常
    System.out.println("===================");
    System.out.println(blockingDeque.offer("d"));
    //peek取队列头元素
    System.out.println(blockingDeque.peek());
    System.out.println("===================");
    //取数组队列元素
    System.out.println(blockingDeque.poll());
    System.out.println(blockingDeque.poll());
    System.out.println(blockingDeque.poll());
}

第三组阻塞API使用

/**
 * 等待 一直阻塞
 */
public static void test2() throws InterruptedException {
    //自定义数组队列的数量
    ArrayBlockingQueue blockingQueue=new ArrayBlockingQueue<>(3);
    //添加到队列
    blockingQueue.put("a");
    blockingQueue.put("b");
    blockingQueue.put("c");

    System.out.println(blockingQueue.take());
    System.out.println(blockingQueue.take());
    System.out.println(blockingQueue.take());
    //如果超出数组队列的范围就会等待
    System.out.println(blockingQueue.take());
}

第四组API使用设置阻塞时间 超过阻塞时间没放进去就放弃等待

public static void test3() throws InterruptedException {
    //自定义数组队列的数量
    ArrayBlockingQueue blockingDeque=new ArrayBlockingQueue<>(3);
    //offer添加元素,如果添加成功会返回true
    System.out.println(blockingDeque.offer("a"));
    System.out.println(blockingDeque.offer("b"));
    System.out.println(blockingDeque.offer("c"));

    //等待2秒后退出
    System.out.println(blockingDeque.offer("d",2, TimeUnit.MILLISECONDS));
    //peek取队列头元素
    System.out.println(blockingDeque.peek());
    System.out.println("===================");
    //取数组队列元素
    System.out.println(blockingDeque.poll());
    System.out.println(blockingDeque.poll());
    System.out.println(blockingDeque.poll());
    //等待2秒后退出
    blockingDeque.poll(10,TimeUnit.MILLISECONDS);
}
SynchronousQueue同步队列
     /**
     * 和其他BlockingQueue不一样,SynchronousQueue不存储元素
     * put进一个元素,就必须take取出来,否则不能继续put
     * @param args
     */
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 {
            Thread.sleep(3);
            System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
            Thread.sleep(3);
            System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
            Thread.sleep(3);
            System.out.println(Thread.currentThread().getName()+"=>"+blockingQueue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    },"T2").start();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值