阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

并发编程ConcurrentLinkedQueue使用示例详解

31次阅读
没有评论

共计 1696 个字符,预计需要花费 5 分钟才能阅读完成。

导读 这篇文章主要为大家介绍了并发编程 ConcurrentLinkedQueue 使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
ConcurrentLinkedQueue

ConcurrentLinkedQueue 是非阻塞线程安全的队列,适用于高并发的场景。是一个基于链接节点的无界线程安全队列,按照 FIFO(先进先出)原则对元素进行排序。队列元素中不可以放置 null 元素(内部实现的特殊节点除外)

并发编程 ConcurrentLinkedQueue 使用示例详解

ConcurrentLinkedQueue 原理
  • ConcurrentLinked 是由链表结构组成的线程安全的先进先出无界队列。
  • 当多线程要共享访问集合时,ConcurrentLinkedQueue 是一个比较好的选择。
  • 不允许插入 null 元素
  • 支持非阻塞地访问并发安全的队列,不会抛出 ConcurrentModifiationException 异常。
  • size 方法不是准确的,因为在统计集合的时候,队列可能正在添加元素,导致统计不准。
  • 批量操作 addAll、removeAll、retainAll、containsAll、equals 和 toArray 不保证原子性(操作不可分割)
  • 添加元素 happen-before 其他线程移除元素。
  • ConcurrentLinkedQueue 类继承 AbstractQueue 抽象类

    具有队列的功能; 实现了 Queue 接口,可作为队列使用。

  • ConcurrentLinkedQueue 继承于 AbstractQueue。
  • ConcurrentLinkedQueue 内部是通过链表来实现的。同时包含链表的头节点 head 和尾节点 tail。
  • ConcurrentLinkedQueue 按照 FIFO(先进先出)原则对元素进行排序。元素都是从尾部插入到链表,从头部开始返回。
  • ConcurrentLinkedQueue 的链表 Node 中的 next 的类型是 volatile,而且链表数据 item 的类型也是 volatile。ConcurrentLinkedQueue 就是通过 volatile 来实现多线程对竞争资源的互斥访问的。
  • 其中 head 节点存放链表第一个 item 为 null 的节点,tail 则并不是总指向最后一个节点
  • ConcurrentLinkedQueue 操作方法
    private transient volatile Node head;
    private transient volatile Node tail;
    public ConcurrentLinkedQueue() {head = tail = new Node(null);
    }

    构造函数中,新建了一个“内容为 null 的节点”,并设置表头 head 和表尾 tail 的值为新节点。head 和 tail 是 volatile 类型,具有 volatile 赋予的含义:“即对一个 volatile 变量的读,总是能看到(任意线程)对这个 volatile 变量最后的写入”。

    private static class Node {
        volatile E item;
        volatile Node next;
        Node(E item) {UNSAFE.putObject(this, itemOffset, item);
        }
    }

    Node 是单向链表节点,next 指向下一个 Node,item 用于存储数据。Node 中操作节点数据的 API,是通过 Unsafe 机制的 CAS 函数实现的;例如 casNext() 是通过 CAS 函数“比较并设置节点的下一个节点”。

    1、添加

    以 add(E e) 为例对 ConcurrentLinkedQueue 中的添加

    public boolean add(E e) {return offer(e);
    }

    add() 实际上是调用的 offer() 来完成添加操作的;offer(E e) 的作用就是将元素 e 添加到链表的末尾。

    2、删除

    poll():在链表头部获取并且移除一个元素

    poll() 的作用就是删除链表的表头节点,并返回被删节点对应的值。

    3、peek 操作

    peek 操作是获取链表头部一个元素(只读取不移除)。

    阿里云 2 核 2G 服务器 3M 带宽 61 元 1 年,有高配

    腾讯云新客低至 82 元 / 年,老客户 99 元 / 年

    代金券:在阿里云专用满减优惠券

    正文完
    星哥说事-微信公众号
    post-qrcode
     0
    星锅
    版权声明:本站原创文章,由 星锅 于2024-07-24发表,共计1696字。
    转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
    【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
    阿里云-最新活动爆款每日限量供应
    评论(没有评论)
    验证码
    【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中