最近在复习多线程的知识,必然少不了要扫描一遍JUC包下的各个类或接口,今天就先来聊一聊阻塞队列BlockingQueue;

BlockingQueue是jdk1.5发布的JUC包下的一个工具类,他提供了天生阻塞的拿(put)和取(take)元素的方法,线程安全,通过其阻塞的put、take方法能很好的实现生产者消费者模型,解决线程间的通信问题,

下面先分别介绍其本身拥有的一些特性方法和实现类

特性方法

boolean add(E e);        添加元素,成功返回true,失败返回false,如果队列设置了长度,超长会抛java.lang.IllegalStateException: Queue full异常

void put(E e);               阻塞式的添加元素,如果队列超长当前线程会一直阻塞,直到队列里的元素被take可以成功添加为止

boolean offer(E e);       添加元素,成功返回true,失败返回false,与add的区别在于队列满了添加失败不会抛异常而是返回false

E take();                        阻塞式的获取队列元素,只要take不到元素当前线程会一直阻塞,直到队列里有元素并成功获取

E poll();                        从队列头部获取并移除元素,获取不到返回null

E peek();                      从队列头部获取元素但不移除元素,获取不到返回null

int drainTo(Collection<? super E> c);   将队列中的元素全部移除,并发送到给定的集合中,返回的是操作成功的元素个数

特性方法对应的测试用例

/**
* @description: 阻塞队列的常用方法测试
* @author: dll
* @date: Created in 2022/1/6 14:47
* @version:
* @modified By:
*/
public class T08_TestBlockingQueue { public static void main(String[] args) throws InterruptedException {
testDrainTo();
} /**
* 将队列中的元素全部移除,并发送到给定的集合中。
*/
private static void testDrainTo () {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.add("1");
queue.add("3");
ArrayList list = new ArrayList();
System.out.println("queue.peek() = " + queue.peek());
int i = queue.drainTo(list);
System.out.println("i = " + i);
System.out.println("list.toString() = " + list.toString());
System.out.println("queue.peek() = " + queue.peek());
} /**
* 从队列头部获取并移除元素,获取不到为null
*/
private static void testPoll() {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
queue.add("123");
System.out.println("queue.poll(1) = " + queue.poll());
System.out.println("queue.remainingCapacity() = " + queue.remainingCapacity());
System.out.println("queue.poll(2) = " + queue.poll());
} /**
* 阻塞式的获取队列元素,只要take不到元素当前线程会一直阻塞,直到队列里有元素并成功获取
*/
private static void testTake() throws InterruptedException {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
queue.add("456");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
queue.put("123");
System.out.println("queue.take() = " + queue.take());
// 此处会阻塞住,直到上面的线程唤醒后往队列添加了元素
System.out.println("queue.take() = " + queue.take());
} /**
* 添加元素,成功返回true,失败返回false,如果队列设置了长度,超长会抛java.lang.IllegalStateException: Queue full异常
* 参数不能为null
*/
private static void testAdd() {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
System.out.println("queue.offer() = " + queue.add("123"));
System.out.println("queue.offer() = " + queue.add("123"));
} /**
* 添加元素,成功返回true,失败返回false,与add的区别在于队列满了添加失败不会抛异常而是返回false
* 参数不能为null
*/
private static void testOffer() {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
System.out.println("queue.offer() = " + queue.offer("123"));
System.out.println("queue.offer() = " + queue.offer("123"));
} /**
* 测试put方法的阻塞式添加
* 阻塞式的添加元素,如果队列超长当前线程会一直阻塞,直到队列里的元素被take可以成功添加为止
* 参数不能为null
* @throws InterruptedException
*/
private static void testPut() throws InterruptedException {
BlockingQueue<String> queue = new ArrayBlockingQueue<>(1);
new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(5);
// 此处用peek下面的put方法仍会阻塞,因为peek只是拿出元素并不会将元素从队列移除
System.out.println("线程里获取到的元素:" + queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
System.out.println("queue.add() = " + queue.add("1"));
// 此处调用会阻塞当前线程,直至上面的线程被唤醒从队列里拿走一个元素
queue.put("12");
System.out.println("主线程里take的元素:" + queue.take());
} }

关于实现类我也不想利用文本的方式一个个列起来了,下面直接附上我整理的思维导图的部分截图,简单明了:

需要注意的是,BlockingQueue的一众实现类是线程池接收任务队列的多种实现,不同的队列应用于不同场景下的线程池;后面会抽时间写一篇关于线程池的总结笔记

BlockingQueue家族成员一览的更多相关文章

  1. Hadoop学习笔记【Hadoop家族成员概述】

    Hadoop家族成员概述 一.Hadoop简介 1.1 什么是Hadoop? Hadoop是一个分布式系统基础架构,由Apache基金会所开发,目前Yahoo!是其最重要的贡献者. Hadoop实现了 ...

  2. hadoop家族成员

    1.概述 使用hadoop已经有一段时间了,从最开始懵懂到迷茫,再到各种阅读与写作,再到如今各种组合应用,逐渐已经离不开hadoop了,hadoop在大数据行业的成功,加速了它本身的发展,各大社区都能 ...

  3. spring-boot-starter家族成员简介

    应用程序starters 以下应用程序starters是Spring Boot在org.springframework.boot组下提供的: springboot使用指南https://docs.sp ...

  4. ARM版本系列及家族成员梳理

    ARM公司简介 ARM是Advanced RISC Machines的缩写,它是一家微处理器行业的知名企业,该企业设计了大量高性能.廉价.耗能低的RISC (精简指令集)处理器. 1985年第一个AR ...

  5. Eolink家族成员回归 — 开源服务Eoapi!

    Eolink 开源产品又回来了!Eoapi 自 2016 年上架 Github 以来,一直备受国内外开发者的欢迎和好评 ,在2018年 Eolink 为了进一步升级该产品而进行了暂时下架.时隔四年,E ...

  6. BlockingQueue队列学习

    今天看了下BlockingQueue的几种实现,记录下以便以后复习. 首先来看一下BlockingQueue的家族成员: BlockingQueue除了先进先出外,还有两个操作:在队列为空时,获取元素 ...

  7. 整理分布式锁:业务场景&分布式锁家族&实现原理

    1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...

  8. 家族企业的常青之道——leo鉴书68

    <Leo鉴书(第1辑)>已登陆百度阅读,今后还将不断更新.免费下载地址:http://t.cn/RvawZEx 企业怎样长久传承.怎样长期有效操持活力.是多元化经营还是集中精力打一点,这些 ...

  9. IPFS家族(一)

    IPFS这个项目其实很大,并不像大家想象的是一个东西,IPFS是由很多模块组成,每一个模块现在都已经独立成项目了,并且有自己的主页.让我们来简单看一下IPFS家族成员. 协议实验室的主页:https: ...

随机推荐

  1. [SDOI2017]序列计数 (矩阵加速,小容斥)

    题面 Alice想要得到一个长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数. Alice还希望,这n个数中,至少有一个数是质数. Alice想知道,有多少个序列满足她的要求 ...

  2. 简易的AutoPlayCarousel 轮播控件

    原理是使用StackPanel 的margin属性的偏移来实现轮播的效果 废话不多说直接上代码 AutoPlayCarousel核心代码 [ContentProperty(nameof(Childre ...

  3. 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(16)-Fiddler如何充当第三者,再识AutoResponder标签-上篇

    1.简介 Fiddler充当第三者,主要是通过AutoResponder标签在客户端和服务端之间,Fiddler抓包,然后改包,最后发送.AutoResponder这个功能可以算的上是Fiddler最 ...

  4. 在 C# CLR 中学习 C++ 之了解 namespace

    一:背景 相信大家在分析 dump 时,经常会看到 WKS 和 SRV 这样的字眼,如下代码所示: 00007ffa`778a07b8 coreclr!WKS::gc_heap::segment_st ...

  5. 第四十七篇:webpack的基本使用(一) --安装和配置webpack

    好家伙, 1.webpack的基本使用 写个例子:实现一个奇偶行变色列表 步骤如下: ① 新建项目空白目录,并运行 npm init-y命令,初始化包管理配置文件 package.json② 新建sr ...

  6. Linux_more_less总结

    先写结论 : less is more,使用less 优于使用more more 和 less的区别 优于more不能后退,而less 就在其基础上增加了后退功能 less 可以使用键盘上的上下方向键 ...

  7. aardio 编程语言快速入门 —— 语法速览

    本文仅供有编程基础的用户快速了解常用语法.如果『没有编程基础』 ,那么您可以通过学习任何一门编程语言去弥补你的编程基础,不同编程语言虽然语法不同 -- 编程基础与经验都是可以互通的.我经常看到一些新手 ...

  8. 新建Github仓库并上传本地代码

    按照Github的教程 Adding a local repository to GitHub using Git 1. 创建空的Github仓库 创建远程仓库 ,注意不要勾选Add a README ...

  9. SpringBoot使用libreoffice转换PDF

    1.简介 有时候我们需要在程序中使用到office的转换和预览功能,本文就针对这个需求记录了较为简单的office转换和功能:jodconverter.当然也有aspose和其他开源第三方(kkfil ...

  10. C++ "链链"不忘@必有回响之单链表

    1. 前言 数组和链表是数据结构的基石,是逻辑上可描述.物理结构真实存在的具体数据结构.其它的数据结构往往在此基础上赋予不同的数据操作语义,如栈先进后出,队列先进先出-- 数组中的所有数据存储在一片连 ...