Java特性队列和栈的堵塞原理解析
作者:cuisuqiang 发布时间:2023-10-13 14:15:55
做消息通信,消息会不断从网络流中取得,而后台也有线程不断消费。本来我一直是使用一些线程安全标识或方法来控制,后来在网上找到一些java新特性,里面包含了可以用到的堆栈使用,而且是堵塞的,这样至少可以保证一些安全性。
对于堆:
BlockingQueue 不接受 null 元素。试图 add、put 或 offer 一个 null 元素时,某些实现会抛出 NullPointerException。null 被用作指示 poll 操作失败的警戒值。
BlockingQueue 可以是限定容量的。它在任意给定时间都可以有一个 remainingCapacity,超出此容量,便无法无阻塞地 put 附加元素。没有任何内部容量约束的 BlockingQueue 总是报告 Integer.MAX_VALUE 的剩余容量。
BlockingQueue 实现主要用于生产者-使用者队列,但它另外还支持 Collection接口。因此,举例来说,使用 remove(x) 从队列中移除任意一个元素是有可能的。然而,这种操作通常不 会有效执行,只能有计划地偶尔使用,比如在取消排队信息时。
BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)没有 必要自动执行,除非在实现 * 别说明。因此,举例来说,在只添加了 c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
看一段代码:
package com.test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* @说明 堵塞队列和栈的使用
*/
public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws InterruptedException {
BlockingQueue bqueue = new ArrayBlockingQueue(5);
for (int i = 0; i < 10; i++) {
// 添加元素到队列,如果没有可用空间,将一直等待(如果有必要)
bqueue.put(i);
System.out.println("添加了元素:" + i);
}
System.out.println("----End----");
}
}
运行效果:
添加了元素:0
添加了元素:1
添加了元素:2
添加了元素:3
添加了元素:4
之后就会一直等待。
对于栈:
BlockingDeque 方法有四种形式,使用不同的方式处理无法立即满足但在将来某一时刻可能满足的操作:第一种方式抛出异常;第二种返回一个特殊值(null 或 false,具体取决于操作);第三种无限期阻塞当前线程,直至操作成功;第四种只阻塞给定的最大时间,然后放弃。
看一个例子:
package com.test;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @说明 堵塞队列和栈的使用
*/
public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws InterruptedException {
BlockingDeque bDeque = new LinkedBlockingDeque(5);
for (int i = 0; i < 10; i++) {
// 将指定元素添加到此阻塞栈中,如果没有可用空间,将一直等待(如果有必要)。
bDeque.putFirst(i);
System.out.println("添加了元素:" + i);
}
System.out.println("----End----");
}
}
运行结果和堆一样,也会产生等待。
对于两者的解释:
阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止。同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止。
对于阻塞栈,与阻塞队列相似。不同点在于栈是“后入先出”的结构,每次操作的是栈顶,而队列是“先进先出”的结构,每次操作的是队列头。
注意的是,BlockingQueue是5中的特性,jdk6以后才增加了BlockingDeque。
来源:https://www.iteye.com/blog/cuisuqiang-1458854


猜你喜欢
- 前言本文给大家分享一个使用Android开发写字板功能Dem、简单操作内存中的图像、对图像进行简单的处理、绘制直线、以达到写字板的效果效果图
- Eureka 采用 CS(Client/Server,客户端/服务器) 架构,它包括以下两大组件:Eureka Server:Eureka
- kafka是什么?Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Kafka是一种高吞吐量的分布式
- SpringMvc中普通类注入Service为null场景:使用Quartz定时器时,普通的java类需要注入spring的service类
- java中的字符串比较竟然不能直接用”==”!!!!而要用equals(),返回true为两字符串相等,返回false为两字符串不相等,举个
- C#反射技术主要基于System.Type类和System.Reflection.Assemble类,通过Type类可以访问关于任何数据类型
- Vitamio是一个功能强大而稳定的播放器库,它支持多种视频格式和编解码方式,并且具有快速、流畅的播放效果,因此在一些对播放质量要求比较高的
- 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的
- 此类的功能包括发送邮件,邮箱格式是否正确,和在不发送邮件的情况下判断邮箱用户名和密码是否正确,鉴于POP检查邮箱用户名和密码出现错误情况返回
- 1.Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务。2.Spring I
- 本文实例讲述了C#实现异步GET的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.Coll
- 一、事务隔离级别①介绍数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事 务与其他事务隔离的程度称为
- 1 修改项目打包类型在pom.xml里,项目打包类型将jar设置成war:<packaging>war</packagin
- 我就废话不多说了,大家还是直接看代码吧~package cn.nxl2018;class Test{ //十进制常量赋值 &n
- 每个Handler对象与创建它的线程相关联,并且每个Handler对象只能与一个线程相关联。Handler一般有两种用途:1)执行计划任务,
- IDEA单元测试报错:Class not found:xxxx springboot报错引入了新依赖,想着在测试模块进行测试。结果报错说Cl
- 传统的Trie实现简单,但是占用的空间实在是难以接受,特别是当字符集不仅限于英文26个字符的时候, * 起来的空间根本无法接受。双数组Trie
- Unsupported major.minor version 51.0解决办法今天偶然间同事遇到一个问题,也加深了自己对eclipse中b
- 一.算法效率算法效率分析分为两种:时间效率、空间效率。其中时间效率被称为时间复杂度,空间效率被称为空间复杂度。时间复杂度主要衡量的是一个算法
- Maven修改打包文件名称对Maven打出的jar包名称不满意:想通过修改配置给jar包改名,查询找到了方法:pom.xml的<bui