【第八章】JUC之阻塞队列BlokingQueue详解

笔记大纲
  • 栈与队列
  • 阻塞队列
  • 阻塞队列的好处
  • BlokingQueue接口的实现类(前3个)
  • BlokingQueue核心方法(4种)
  • BlokingQueue案例应用

一、栈与队列

  栈与队列都是一种数据结构。

  栈:遵循“先进后出”、“后进先出”原则

  队列:遵循“x先进先出”

二、阻塞队列

  阻塞队列是一个队列,它最大的特点就是阻塞的线程满足条件就会被自动唤醒,不需要我们人为的判断。

    当队列为空时,从队列中获取元素的操作就会被阻塞;

    当队列为满时,从队列中添加元素的操作就会被阻塞。

在这里插入图片描述

三、阻塞队列的好处

  之前总结的线程间通信,需要判断对应的值增加1减少1,一个生产者与一个消费者,在判断状态的时候需要加一个标志类,还需要控制线程。而阻塞队列在某些情况会挂起<暂停>线程(阻塞),满足条件,就会被自动的唤起,BlokingQueue一手包办!

四、BlokingQueue接口的实现类
序号实现类说明
1(重点)ArrayBlockingQueue数据结构组成的有界阻塞队列
2(重点)LinkedBlockingQueue链表结构组成的有界阻塞队列(默认大小integer_MAX_VALUE
3(重点)SynchronousQueue不存储元素的阻塞队列(单个元素的队列)
4PriorityBlockingQueue支持优先级排序的无界阻塞队列
5DelayQueue使用优先级队列实现的延迟无界阻塞队列
6LinkedTransferQueue由链表组成的无界阻塞队列。
7LinkedBlockingDeque由链表组成的双向阻塞队列。

在这里插入图片描述

五、BlokingQueue核心方法

(1)抛出异常

  当阻塞队列满时,再往队列里add插入元素会抛IllegalStateException:Queue full
   当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException

(2)特殊值

  offer插入方法,成功ture失败false
   poll移除方法,成功返回出队列的元素,队列里没有就返回null

(3)阻塞

  当阻塞队列满时,生产者线程继续往队列里put元素,队列会一直阻塞生产者线程直到put数据或者响应中断退出;
   当阻塞队列空时,消费者线程试图从队列里take元素,队列会一直阻塞消费者线程直到队列可用。

在这里插入图片描述

六、BlokingQueue案例应用
测试代码1-1(抛出异常方法类型)
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
 * 阻塞队列(接口)
 */
public class BlockQueueDemo {
    public static void main(String[] args) {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        System.out.println(blockingQueue.add("one"));
        System.out.println(blockingQueue.add("two"));
        System.out.println(blockingQueue.add("three"));
        System.out.println(blockingQueue.add("four")); //超出队列初始容量,会报错
    }
}
打印结果

阻塞队列满时,再往队列里add插入元素会抛IllegalStateException:Queue full

在这里插入图片描述

测试代码1-2(抛出异常方法类型)
/**
 * 阻塞队列(接口)--检查队列
 */
public class BlockQueueDemo {
    public static void main(String[] args) {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        System.out.println(blockingQueue.add("one"));
        System.out.println(blockingQueue.add("two"));
        System.out.println(blockingQueue.add("three"));
        System.out.println(blockingQueue.element()); //查看元素
    }
}
打印结果

调用element()方法,检查出第一个添加的元素,遵循“先进先出”原则!

在这里插入图片描述

测试代码1-3(抛出异常方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
public class BlockQueueDemo {
    public static void main(String[] args) {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        System.out.println(blockingQueue.add("one"));
        System.out.println(blockingQueue.add("two"));
        System.out.println(blockingQueue.add("three"));
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());//移除元素,超出队列的容量,报错

    }
}

打印结果

当阻塞队列空时,再往队列里remove移除元素会抛NoSuchElementException

在这里插入图片描述

测试代码2-1(特殊值方法类型)
/**
 * 阻塞队列(接口)--添加元素offer()
 */
public class BlockQueueDemo {
    public static void main(String[] args) {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        System.out.println(blockingQueue.offer("one"));
        System.out.println(blockingQueue.offer("two"));
        System.out.println(blockingQueue.offer("three"));
        System.out.println(blockingQueue.offer("four"));//不抛异常,成功返回true,失败返回false
    }
}
打印结果

在这里插入图片描述

测试代码2-2(特殊值方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
public class BlockQueueDemo {
    public static void main(String[] args) {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        System.out.println(blockingQueue.offer("one"));
        System.out.println(blockingQueue.offer("two"));
        System.out.println(blockingQueue.offer("three"));

        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());//成功返回出队列的元素,队列里没有就返回`null`
    }
}
打印结果

在这里插入图片描述

测试代码3-1(阻塞方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
public class BlockQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        //初始化阻塞队列容量是3
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
        //第一组
        blockingQueue.put("one");
        blockingQueue.put("two");
        blockingQueue.put("three");
        blockingQueue.put("four");
    }
}
打印结果

…阻塞中,无任何结果!

测试代码3-2(阻塞方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
        public class BlockQueueDemo {
            public static void main(String[] args) throws InterruptedException {
                //初始化阻塞队列容量是3
                BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
                //第一组
                blockingQueue.put("one");
                blockingQueue.put("two");
                blockingQueue.put("three");
                
                System.out.println(blockingQueue.take());
                System.out.println(blockingQueue.take());
                System.out.println(blockingQueue.take());
                System.out.println(blockingQueue.take());//阻塞中,不会结束(不见不散)

            }
        }

打印结果

在这里插入图片描述

测试代码4-1(超时方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
        public class BlockQueueDemo {
            public static void main(String[] args) throws InterruptedException {
                //初始化阻塞队列容量是3
                BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
                //第一组
                System.out.println(blockingQueue.offer("one"));
                System.out.println(blockingQueue.offer("two"));
                System.out.println(blockingQueue.offer("three"));
                //超时3s后,成功返回true,失败返回false
                System.out.println(blockingQueue.offer("four", 3, TimeUnit.SECONDS));

            }
        }

打印结果

在这里插入图片描述

测试代码4-2(超时方法类型)
/**
 * 阻塞队列(接口)--移除元素
 */
        public class BlockQueueDemo {
            public static void main(String[] args) throws InterruptedException {
                //初始化阻塞队列容量是3
                BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<String>(3);
                //第一组
                System.out.println(blockingQueue.offer("one"));
                System.out.println(blockingQueue.offer("two"));
                System.out.println(blockingQueue.offer("three"));


                System.out.println(blockingQueue.poll());
                System.out.println(blockingQueue.poll());
                System.out.println(blockingQueue.poll());
                System.out.println(blockingQueue.poll(3, TimeUnit.SECONDS));

            }
        }

打印结果

在这里插入图片描述


 ☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值