阻塞队列(BlockingQueue)

2024-04-04 11:20
文章标签 队列 阻塞 blockingqueue

本文主要是介绍阻塞队列(BlockingQueue),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 何为阻塞队列
  1. 当阻塞队列是空时,从队列中获取元素的操作将被阻塞
  2. 当阻塞队列是满时,往队列中添加元素将会被阻塞
  3. 试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他线程往空的队列中插入新的元素
  4. 试图往满的队列中,添加新的元素的线程也会被阻塞,直到其他线程从队列中移除一个或多个元素或完全清空队列后使队列重新变得空闲起来后并后续新增
  • 为什么用?有什么好处?
    在多线程领域:所谓阻塞,在某些情况下会刮起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤醒。阻塞队列的好处是,我们不需要关心什么时候需要阻塞线程,什么时候唤醒线程。在concurrent包发布以前,在多线程环境下,我们每个程序员都必须去自己控制这些细节,尤其还要兼顾效率和线程安全,而这会给我们程序带来不小的复杂度。

  • 队列的实现

  • 核心方法

  1. 抛出异常组
 BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);System.out.println(blockingQueue.add("a"));System.out.println(blockingQueue.add("b"));System.out.println(blockingQueue.add("c"));// Exception in thread "main" java.lang.IllegalStateException: Queue full// 超过容量,抛出异常// System.out.println(blockingQueue.add("d"));// 检查元素 顶端元素  System.out.println(blockingQueue.element());// 按顺序删除System.out.println(blockingQueue.remove());System.out.println(blockingQueue.remove());System.out.println(blockingQueue.remove());
  1. 返回特殊值
        System.out.println(blockingQueue.offer("a"));System.out.println(blockingQueue.offer("b"));System.out.println(blockingQueue.offer("c"));System.out.println(blockingQueue.offer("d")); // false 不会抛出异常// 检查队列顶部元素System.out.println(blockingQueue.peek());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll());System.out.println(blockingQueue.poll()); // 没有第四个 获取null
  1. 一直阻塞
        blockingQueue.put("a");blockingQueue.put("b");blockingQueue.put("c");System.out.println("=======================");// blockingQueue.put("d");  // 放第四个的时候,没有位置了,线程阻塞,等待空位置blockingQueue.take();blockingQueue.take();blockingQueue.take();blockingQueue.take(); // 取第四个的时候,队列里还没有,线程阻塞 
  1. 超时阻塞
        // 立即插入,不用等待2秒System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));System.out.println(blockingQueue.offer("a", 2L, TimeUnit.SECONDS));System.out.println(blockingQueue.poll(2L,TimeUnit.SECONDS));System.out.println(blockingQueue.poll(2L,TimeUnit.SECONDS));System.out.println(blockingQueue.poll(2L,TimeUnit.SECONDS));System.out.println(blockingQueue.poll(2L,TimeUnit.SECONDS)); // 阻塞两秒,返回null
  • SynchronousQueue
// 放一个,取了再放一个,如果不取则不放,队列里面只能有一个 new Thread(() -> {try {System.out.println(Thread.currentThread().getName() +"\t put 1 ");blockingQueue.put("1");System.out.println(Thread.currentThread().getName() +"\t put 2 ");blockingQueue.put("2");System.out.println(Thread.currentThread().getName() +"\t put 3 ");blockingQueue.put("3");} catch (InterruptedException e) {e.printStackTrace();}},"aaa").start();new Thread(() -> {try {TimeUnit.SECONDS.sleep(5);System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());TimeUnit.SECONDS.sleep(5);System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());TimeUnit.SECONDS.sleep(5);System.out.println(Thread.currentThread().getName() + "\t" + blockingQueue.take());} catch (InterruptedException e) {}},"bbb").start();

这篇关于阻塞队列(BlockingQueue)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/875641

相关文章

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s

poj 2431 poj 3253 优先队列的运用

poj 2431: 题意: 一条路起点为0, 终点为l。 卡车初始时在0点,并且有p升油,假设油箱无限大。 给n个加油站,每个加油站距离终点 l 距离为 x[i],可以加的油量为fuel[i]。 问最少加几次油可以到达终点,若不能到达,输出-1。 解析: 《挑战程序设计竞赛》: “在卡车开往终点的途中,只有在加油站才可以加油。但是,如果认为“在到达加油站i时,就获得了一

poj3750约瑟夫环,循环队列

Description 有N个小孩围成一圈,给他们从1开始依次编号,现指定从第W个开始报数,报到第S个时,该小孩出列,然后从下一个小孩开始报数,仍是报到S个出列,如此重复下去,直到所有的小孩都出列(总人数不足S个时将循环报数),求小孩出列的顺序。 Input 第一行输入小孩的人数N(N<=64) 接下来每行输入一个小孩的名字(人名不超过15个字符) 最后一行输入W,S (W < N),用

POJ2010 贪心优先队列

c头牛,需要选n头(奇数);学校总共有f的资金, 每头牛分数score和学费cost,问合法招生方案中,中间分数(即排名第(n+1)/2)最高的是多少。 n头牛按照先score后cost从小到大排序; 枚举中间score的牛,  预处理左边与右边的最小花费和。 预处理直接优先队列贪心 public class Main {public static voi

Java并发编程之——BlockingQueue(队列)

一、什么是BlockingQueue BlockingQueue即阻塞队列,从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种: 1. 当队列满了的时候进行入队列操作2. 当队列空了的时候进行出队列操作123 因此,当一个线程试图对一个已经满了的队列进行入队列操作时,它将会被阻塞,除非有另一个线程做了出队列操作;同样,当一个线程试图对一个空

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

多路转接之select(fd_set介绍,参数详细介绍),实现非阻塞式网络通信

目录 多路转接之select 引入 介绍 fd_set 函数原型 nfds readfds / writefds / exceptfds readfds  总结  fd_set操作接口  timeout timevalue 结构体 传入值 返回值 代码 注意点 -- 调用函数 select的参数填充  获取新连接 注意点 -- 通信时的调用函数 添加新fd到

FreeRTOS学习笔记(六)队列

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、队列的基本内容1.1 队列的引入1.2 FreeRTOS 队列的功能与作用1.3 队列的结构体1.4 队列的使用流程 二、相关API详解2.1 xQueueCreate2.2 xQueueSend2.3 xQueueReceive2.4 xQueueSendFromISR2.5 xQueueRecei

多线程篇(阻塞队列- LinkedBlockingDeque)(持续更新迭代)

目录 一、LinkedBlockingDeque是什么 二、核心属性详解 三、核心方法详解 addFirst(E e) offerFirst(E e) putFirst(E e) removeFirst() pollFirst() takeFirst() 其他 四、总结 一、LinkedBlockingDeque是什么 首先queue是一种数据结构,一个集合中