浅谈Java队列Queue

队列Queue就是一个先进先出的数据结构,与List、Set同一级别,继承了Collection接口。

一、Queue的实现

1、阻塞队列(BlockingQueue)

① 插入:队列不满时可执行插入元素线程,直到队列满。

② 移除:队列不为空都可移除,直到队列为空。

621aa61edfdfc58f8c71cf9cf721f141306.jpg

抛出异常:满的时候插入,空的时候取出都会抛异常。

返回特殊值:插入成功返回true

一直阻塞:满时put和空时take会阻塞线程,直到队列可用。

超时退出:满时会阻塞插入一段时间,如果超过一定时间,线程就会退出。

JDK7提供了7个阻塞队列:

① ArrayListBlockingQueue

ArrayBlockingQueue是一个由数组支持的有界阻塞队列。在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。 
② LinkedBlockingQueue

一个由链表结构组成的双向阻塞队列。

基于链表的阻塞队列,内部维持这一关数据缓冲队列。当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;当队列缓冲区达到最大缓冲容量时,才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生成者线程才会被唤醒,反之对消费者的处理也基于同样的原理。

LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者和消费者分别采用了独立的锁来控制数据同步,也就意味着在高并发的情况下生产者和消费者可以并行的操作队列中的数据,以此来提高整个队列的并发性能。

③ SynchronousQueue

一个不存储元素的阻塞队列,在某次添加元素后必须等待其他线程取走后才能继续添加。

④ PriorityBlockingQueue 

是一个带优先级的队列,而不是先进先出队列,该队列也没有上限,但是如果队列为空,那么取元素的操作take就会阻塞。

⑤ DelayQueue

是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。

ArrayListBlockingQueue和LinkedBlockingQueue的区别?

① 队列中锁的实现不同

ArrayBlockingQueue生产者消费者使用同一个锁。

LinkedBlockingQueue生产用的是putLock,消费是takeLock。

② 在生产和消费时操作不同

ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;

LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为节点进行插入或移除,会影响性能。

③ 队列大小初始化方式不同

ArrayBlockingQueue实现的队列必须指定大小

LinkedBlockingQueue可以不指定大小,默认是Integer.MAX_VALUE

ArrayBlockingQueue性能要比LinkedBlockingQueue性能要好,执行速度更快,ArrayBlockingQueue优先使用!

2、非阻塞队列

ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部;当我们获取一个元素时,它会返回队列头部的元素。

入队和出队操作均利用CAS(compare and set)更新,这样允许多个线程并发执行,并且不会因为加锁而阻塞线程,使得并发性能更好。

注:CAS用于实现多线程同步的原子指令,它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 

二、代码实例

package OSChina.Client;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class BlockingQueueTest {
    static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    //定义装苹果的篮子
    public static class Basket{
        // 篮子,能够容纳3个苹果
       static BlockingQueue<String> queue = new ArrayBlockingQueue<String>(3);
        //生产苹果,放入篮子
        public void produce() throws InterruptedException{
            queue.put("An apple");
        }
        // 消费苹果,从篮子中取走
        public String consume() throws InterruptedException{
            String apple = queue.take();
            return apple;
        }
        public static int getAppleNumber(){
            return queue.size();
        }
    }

    public static void testBasket(){
        // 建立一个装苹果的篮子
        final Basket basket = new Basket();
        //定义苹果生产者
        class Producer implements Runnable{
            @Override
            public void run() {
                try {
                    while (true){
                        System.out.println("生产者准备生产苹果:"+sdf.format(new Date())+",篮子中苹果数量:"+Basket.getAppleNumber());
                        basket.produce();
                        System.out.println("生产者生产苹果完毕:" + sdf.format(new Date())+",篮子中苹果数量:"+Basket.getAppleNumber());
                        Thread.sleep(300);
                    }
                }catch (InterruptedException  ex){
                }
            }
        }
        //定义苹果消费者
        class Consumer implements Runnable{
            @Override
            public void run() {
                try {
                    while (true){
                        System.out.println("消费者准备消费苹果:" + sdf.format(new Date())+",篮子中苹果数量:"+Basket.getAppleNumber());
                        basket.consume();
                        System.out.println("消费完后有苹果:" + sdf.format(new Date())+",篮子中苹果数量:"+Basket.getAppleNumber());
                        Thread.sleep(1000);
                    }
                }catch (InterruptedException ex){
                }
            }
        }

        ExecutorService service = Executors.newFixedThreadPool(2);
        Producer producer = new Producer();
        Consumer consumer = new Consumer();
        service.submit(producer);
        service.submit(consumer);
        // 程序运行10s后,所有任务停止
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        service.shutdownNow();
    }

    public static void main(String[] args) {
        BlockingQueueTest.testBasket();
    }
}

aa436635ebc6e8caa2f0431a2316f7035ee.jpg

 

江疏影讲Java@目录

转载于:https://my.oschina.net/u/4006148/blog/3076136

Java集合框架】08 ——Queue 接口 Queue接口 阅读详情

相关推荐

Java队列Queue的使用

Queue   Queue接口List、Set同一级别,都是继承了Collection接口。LinkedList实现了Queue接 口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。 BlockingQueue(阻塞队列) 继承了Queue接口,涉及到多线程后面会讲。 Que...

yuan_dai_ma的博客 2103

tmp

inorder-traversal-java init a arraylist non - recursion : need a extra treenode current pop function of stack returns the top element in java

William Zhao's notes 850

不用Root也能抓包?Android高版本HTTPS抓包的3种替代方案(含Charles技巧)

本文针对Android高版本HTTPS抓包难题,提供了三种无需Root权限的实战解决方案:利用VirtualXposed等虚拟沙盒环境、配置Postern等系统级代理工具,以及通过修改应用源码或网络安全配置。文章还详细解析了Charles抓包工具在非Root环境下的高级配置排错技巧,帮助开发者在遵守安全规范的前提下,有效进行网络调试监控。

http9protocoller的博客 554

JAVA队列Queue)用法附实例讲解

队列用于模拟队列这种数据结构队列通常是指“先进先出”的容器。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。

机智大头 1万+

java堆栈队列_java集合框架:浅谈如何使用LInkedList实现队列(Queue)和堆栈(Stack)

Java中的LinkedList是采用双向循环列表实现的。利用LinkedList可以实现栈(stack)、队列(queue)下面写两个例子学生类:int stuId;public int getStuId() {return stuId;}public void setStuId(int stuId) {this.stuId = stuId;}public String getStuName...

weixin_32601937的博客 217

java集合框架:浅谈如何使用LInkedList实现队列(Queue)和堆栈(Stack)

Java中的LinkedList 是采用双向循环列表实现的。 利用LinkedList 可以实现栈(stack)、队列queue) 感兴趣的可以群:854393687 下面写两个例子 学生类: int stuId; public int getStuId() { return stuId; } public void setStuId(int stuId) { this.stuId = stu...

javarrr的博客 432

java中list 堆栈,java集合框架:浅谈如何使用LInkedList实现队列(Queue)和堆栈(Stack)

下面写两个例子学生类:int stuId;public int getStuId() {return stuId;}public void setStuId(int stuId) {this.stuId = stuId;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this....

weixin_33735281的博客 334

java堆栈功能队列_java集合框架:浅谈如何使用LInkedList实现队列(Queue)和堆栈(Stack)...

下面写两个例子学生类:int stuId;public int getStuId() {return stuId;}public void setStuId(int stuId) {this.stuId = stuId;}public String getStuName() {return stuName;}public void setStuName(String stuName) {this....

weixin_35078410的博客 107

java队列——queue浅析

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34054931的博客 105

Queue、Deque用法浅谈

java Queue、Deque用法

qq_52462620的博客 1020

数据结构队列-Queue

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(FirstIn First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear)出队列:进行删除操作的一端称为队头(Head/Front)

iLoyo_的博客 626

Java队列Queue)用法

Java队列queue的用法 数据结构 队列

Sueko的博客 3万+

Java】关于Queue的用法总结

之前对Queue只有一知半解,常用它的某几个方法,却不知道其中的区别,看了官方文档今天来总结一下。 一、简介: Interface Queue&lt;E&gt; 出自Java.util,是个公共接口,它的父接口有我们熟知的Collection&lt;E&gt;和Iterable&lt;E&gt; (这两个有空再总结),它的子接口有:BlockingDeque&lt;E&gt;,Block...

Max的专栏 1万+

java中的Queue队列的用法

大家好,欢迎来到雄雄的小课堂,今天给大家分享的是“java中的Queue队列的用法” 前言:好多人对Queue不是很熟悉,毕竟平时也不怎么用,遇到集合要么List要么map这些常用的,殊不知,java中还有个Queue,今天,我们就来看看Queue的用法。 何为队列队列是一种特殊数据结构,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,“先进先出”的场景,和我们生活中的排队类似,谁先来先给谁办理。 Queue队列 Java中,LinkedList类就是实现的Queue接口,因此,我们可以把L.

穆雄雄的博客 3257

JAVA数据篇-队列Queue使用

Java 中,队列Queue)是一种用于存储和管理元素的线性数据结构,遵循先进先出(FIFO)的原则,即最先进入队列的元素最先被取出。Java 中提供了多种队列的实现类,常用的包括 LinkedList、ArrayDeque 和 PriorityBlockingQueue 等。。Java 中的队列 (Queue) 是一种先进先出 (FIFO) 的数据结构,用于存储元素并按照它们被添的顺序进行访问。

拽着尾巴的鱼儿的博客 2516

java Queue 详解

java Queue 详解

T_Y_F_的博客 2369

java队列(Queue)用法总结

1.队列的特点 队列是一种比较特殊的线性结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中最先插入的元素也将最先被删除,对应的最后插入的元素将最后被删除。因此队列又称为“先进先出”(FIFO—first in first out)的线性表,栈(FILO-first in last out)刚好相反...

bitcarmanlee的博客 6万+

ubuntu24.04+RTX5090D 显卡驱动安装

本文详细介绍了在Ubuntu系统中更新内核、安装NVIDIA驱动的步骤。首先,通过mainline工具安装新版内核,并确保GCC版本兼容。接着,在无桌面环境下配置TTY模式,解决中文显示问题。然后,禁用默认的nouveau驱动,安装NVIDIA驱动,并选择开源驱动以避免黑屏问题。最后,重新启用图形界面,并通过测试软件验证显卡功能。整个过程涵盖了内核更新、驱动安装、TTY配置及图形界面恢复等多个关键步骤,适合需要手动配置NVIDIA驱动的用户参考。

妖米的博客 4591

纸箱实例分割数据集_20251120_013033.zip

纸箱实例分割数据集一、基础信息• 数据集名称:纸箱实例分割数据集• 图片数量:训练集:2164张图片验证集:308张图片测试集:152张图片总计:2624张图片• 训练集:2164张图片• 验证集:308张图片• 测试集:152张图片• 总计:2624张图片• 分类类别:Box(纸箱)• 标注格式:YOLO格式,包含实例分割的多边形标注,适用于实例分割任务。• 数据格式:图片来源于实际场景,标注精确。二、适用场景• 物流仓储自动化:用于自动识别和分割仓库环境中的纸箱,支持智能库存管理、分拣系统和包裹跟踪。• 制造业质量检查:检测生产线上纸箱的完整性和位置,辅助质量控制和流程优化。• 机器人视觉:为工业机器人提供精确的纸箱轮廓信息,实现准确的抓取、放置和操作。• 运输包装优化:优化包装设计、运输物流中的箱子处理,提高效率和减少资源浪费。三、数据集优势• 高精度实例分割标注:每个纸箱实例均采用多边形标注,确保轮廓细节准确,适用于精细的实例分割模型训练。• 数据多样性:数据集涵盖多种场景下的纸箱图像,增强模型在不同环境下的泛化能力和鲁棒性。• 即插即用兼容性:标注格式兼容YOLO等主流深度学习框架,便于快速集成和实验,缩短开发周期。• 实际应用价值:专注于物流、制造等行业的常见需求,为AI模型在真实环境中的部署提供可靠数据支撑。

上一篇: Java多线程之Executor框架<Callable、Future、Executor和ExecutorService>
下一篇: 编写高质量代码:改善Java程序的151个建议(第6章:枚举和注解___建议83~92)
chetianyao8457
博客等级 码龄10年 7粉丝 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值