首页 > 编程语言 >Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentLinkedDeque

Java 入门指南:Java 并发编程 —— 并发容器 ConcurrentLinkedDeque

时间:2024-09-07 22:51:20浏览次数:13  
标签:返回 deque Java ConcurrentLinkedDeque 队列 双端 元素 并发

文章目录

ConcurrentLinkedDeque

ConcurrentLinkedDeque 是 Java 并发工具包(java.util.concurrent 包)中的一个线程安全的双端队列(Deque)实现,实现了 Deque 接口。它使用了链表结构,并且针对高并发环境进行了优化,非常适合用于多线程环境中需要安全地并发访问双端队列的情况。ConcurrentLinkedDeque 不使用锁来保证线程安全,而是通过 CAS(Compare and Swap)原子操作来实现线程安全。

特点

  1. 非阻塞ConcurrentLinkedDeque 使用一种非阻塞的算法来实现并发操作,允许多个线程同时进行插入、删除和获取操作,而不需要进行锁定或阻塞。

  2. 线程安全ConcurrentLinkedDeque 提供了线程安全的操作,可以在多线程环境中使用而无需额外的同步操作。

  3. 双向链表ConcurrentLinkedDeque 是一个双向链表,可以在队列的头部和尾部进行插入、删除和获取操作。

  4. 无界容量ConcurrentLinkedDeque 没有容量限制,可以根据需要动态添加和移除元素。

构造方法

  1. 创建一个空的 ConcurrentLinkedDeque
ConcurrentLinkedDeque()
  1. 创建一个包含给定集合中所有元素的 ConcurrentLinkedDeque,元素存储顺序为集合迭代器返回元素的顺序。如果给定集合为空,则创建一个空的 ConcurrentLinkedDeque
ConcurrentLinkedDeque(Collection<? extends E> collection)

常用方法

  • addFirst(E e): 将指定元素插入到双端队列的头部,如果插入成功则返回 true,否则返回 false

  • addLast(E e): 将指定元素插入到双端队列的尾部,如果插入成功则返回 true,否则返回 false

  • offerFirst(E e): 将指定元素插入到双端队列的头部,如果插入成功则返回 true,否则返回 false

  • offerLast(E e): 将指定元素插入到双端队列的尾部,如果插入成功则返回 true,否则返回 false

  • removeFirst(): 移除并返回双端队列的头部元素,如果队列为空,则抛出NoSuchElementException 异常。

  • removeLast(): 移除并返回双端队列的尾部元素,如果队列为空,则抛出NoSuchElementException 异常。

  • pollFirst(): 移除并返回双端队列的头部元素,如果队列为空则返回 null

  • pollLast(): 移除并返回双端队列的尾部元素,如果队列为空则返回 null

  • getFirst(): 返回双端队列的头部元素,但不移除该元素。

  • getLast(): 返回双端队列的尾部元素,但不移除该元素。

  • peekFirst(): 返回双端队列的头部元素,如果队列为空则返回 null

  • peekLast(): 返回双端队列的尾部元素,如果队列为空则返回 null

  • contains(Object o): 判断双端队列是否包含指定的元素。

  • isEmpty(): 判断双端队列是否为空。

  • size(): 返回双端队列的元素个数。

  • iterator(): 返回在此双端队列中元素上按顺序进行迭代的迭代器。

  • descendingIterator(): 返回在此双端队列中元素上按逆序进行迭代的迭代器。

  • spliterator(): 创建一个分离器并行迭代双端队列中的元素。

使用示例

以下是一个简单的 ConcurrentLinkedDeque 使用示例,展示了如何创建一个双端队列,并在其上执行基本的操作:

import java.util.concurrent.ConcurrentLinkedDeque;

public class ConcurrentLinkedDequeExample {

    public static void main(String[] args) {
        // 创建 ConcurrentLinkedDeque
        ConcurrentLinkedDeque<String> deque = new ConcurrentLinkedDeque<>();

        // 添加元素
        deque.offerFirst("Apple");
        deque.offerLast("Banana");
        deque.offerFirst("Cherry");

        // 打印队列
        System.out.println("双端队列初始状态: " + deque);

        // 创建线程向队列中添加元素
        Thread addThread = new Thread(() -> {
            deque.offerFirst("Durian");
            deque.offerLast("Elderberry");
            System.out.println("添加元素后的双端队列: " + deque);
        });

        // 创建线程从队列中取出元素
        Thread pollThread = new Thread(() -> {
            while (!deque.isEmpty()) {
                String itemFirst = deque.pollFirst();
                String itemLast = deque.pollLast();
                if (itemFirst != null) {
                    System.out.println("从队列前端取出元素: " + itemFirst);
                }
                if (itemLast != null) {
                    System.out.println("从队列尾端取出元素: " + itemLast);
                }
            }
        });

        // 启动线程
        addThread.start();
        pollThread.start();

        try {
            // 等待线程结束
            addThread.join();
            pollThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("主线程被中断");
        }

        // 打印最终队列状态
        System.out.println("最终双端队列状态: " + deque);
    }
}

注意事项

使用 ConcurrentLinkedDeque 时,应注意以下问题:

  1. 弱一致性ConcurrentLinkedDeque 提供的是弱一致性保证,这意味着如果存在多个线程并发操作双端队列,双端队列的顺序可能会发生变化。
  2. 非阻塞特性ConcurrentLinkedDequepollFirstpollLast 方法在队列为空时会立即返回 null,而不是阻塞等待。这意味着如果你需要等待双端队列中有元素,应该考虑使用 BlockingDeque
  3. 迭代器快照ConcurrentLinkedDequeiterator 方法返回的是一个快照迭代器,不会反映迭代期间双端队列的变化。如果需要实时迭代双端队列中的元素,可以考虑使用其他机制,如轮询。
  4. 内存回收ConcurrentLinkedDeque 中的节点在没有引用指向时会被垃圾回收。因此,如果双端队列中的元素不再被引用,相应的节点也会被回收。

标签:返回,deque,Java,ConcurrentLinkedDeque,队列,双端,元素,并发
From: https://blog.csdn.net/Zachyy/article/details/141998496

相关文章

  • 【Effective Java】多构造器参数使用构建器 (快速上手)
    Java系列文章目录补充内容Windows通过SSH连接Linux第一章Linux基本命令的学习与Linux历史文章目录Java系列文章目录一、前言二、学习内容:2.1为什么引入构建器2.2建造者模式2.2.1书中的例子2.2.2例子加上有效性检查三、问题描述四、解决方案:4.1类层次结构4.2......
  • 【Java】已解决:java.util.concurrent.CancellationException
    文章目录一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项已解决:java.util.concurrent.CancellationException一、分析问题背景java.util.concurrent.CancellationException是一种常见的运行时异常,当尝试访问已取消的任务时......
  • 【Java】已解决:org.aopalliance.aop.AspectException
    文章目录一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项已解决:org.aopalliance.aop.AspectException一、分析问题背景在使用SpringAOP(面向切面编程)时,开发者有时会遇到org.aopalliance.aop.AspectException报错。这通常发生......
  • 分布式架构下的秒杀优化实战:从高并发到数据一致性
    时间:2024年09月07日作者:小蒋聊技术邮箱:[email protected]微信:wei_wei10音频地址:喜马拉雅希望大家帮个忙!如果大家有工作机会,希望帮小蒋推荐一下,小蒋希望遇到一个认真做事的团队,一起努力。需要简历可以加我微信。大家好,欢迎来到小蒋聊技术,小蒋准备和大家一起聊聊技术的......
  • Javaweb-约束案例
    createtableemp( idintPRIMARYKEYAUTO_INCREMENT, enamevarchar(50)notnullunique, joindatedatenotnull, salarydouble(7,2)notnull, bonusdouble(7,2)default0);insertintoemp(id,ename,joindate,salary,bonus)values(1,'张三',�......
  • Zabbix02 Zabbix告警通知, 故障自愈, 主动被动模式, JAVA应用网络设备等的监控及分布
    图形Graphs#点击web端配置下的模板,选择模板对应的图形,点击右上角创建图标#输入名称TCP状态#监控项选择添加,最后点添加#点击监测下关联该模板的主机,点击图形,就能看到添加的图形#仪表盘为图形的组合#配置下模板里,点击仪表盘栏,点击创建仪表盘,构件可把之前画的图添加出......
  • Java 21的Preferences API的笔记
    JavaCoreLibrariesPreferencesAPI多用户环境下,应用程序保存配置参数的一种API,目前支持用户和系统两类配置。在现有的项目中,目前没有使用过本API。ComparingthePreferencesAPItoOtherMechanisms通常,应用的开发者还可以使用PropertiesAPI或者JNDIAPI。UsageNotes......
  • java 一个对象list 通过获取最大版本的 name值,版本为字符串格式 1 1.1 2 2.1 3
    你可以使用Java的流(Streams)功能来获取具有最大版本的name值。假设你的对象类名为Item,并且包含name和version字段,可以按照以下方式操作:importjava.util.*;importjava.util.stream.*;classItem{Stringname;Stringversion;//Constructor,getters,......
  • Java中Runtime类的学习
    Runtime类目录Runtime类什么是RuntimeRuntime类有哪些方法,有什么用什么是RuntimeRuntime(运行时),每个Java程序在运行时都相当于启动了一个JVM实例,每个JVM实例都对应一个Runtime对象。Runtime对象是由JVM负责实例化的,因此我们无法通过传统的方式实例化一个Runtime对象,只能通过调......
  • 彻底理解JavaScript中的闭包
    闭包是js的一个难点也是它的一个特色,是我们必须掌握的js高级特性,那么什么是闭包呢?它又有什么用呢?我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的变量并且可以获......