zoukankan      html  css  js  c++  java
  • ConcurrentLinkedQueue

    我们要实现一个线程安全的队列有两种实现方式,阻塞算法、非阻塞算法。使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)

    或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环CAS的方式来实现,本节我们就来研究下

    ConcurrentLinkedQueue是如何保证线程安全的同时又能高效的操作的。

    一.ConcurrentLinkedQueue

    当前常用的多线程同步机制可以分为下面三种类型:

    • volatile 变量:轻量级多线程同步机制,不会引起上下文切换和线程调度。仅提供内存可见性保证,不提供原子性

    所以要在多线程中安全使用volatile,必须同时满足

    1、对变量的写入操作不依赖其当前值(不满足:number++、count=count*5等,满足:boolean变量、记录温度变化的变量等);

    2、该变量没有包含在具有其他变量的不变式中(不满足:不变式low < up)

    • CAS 原子指令:轻量级多线程同步机制,不会引起上下文切换和线程调度。它同时提供内存可见性和原子化更新保证。
    • 互斥锁:重量级多线程同步机制,可能会引起上下文切换和线程调度,它同时提供内存可见性和原子性。

    ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,

    它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。基于CAS的“wait-free”(无等待)来实现,CAS并不是一个

    算法,它是一个CPU直接支持的硬件指令,这也就在一定程度上决定了它的平台相关性。

    ConcurrentLinkedQueue 的非阻塞算法实现主要可概括为下面几点:

    • 使用 CAS 原子指令来处理对数据的并发访问,这是非阻塞算法得以实现的基础。
    • head/tail 并非总是指向队列的头 / 尾节点(???),也就是说允许队列处于不一致状态

    这个特性把入队 /出队时,原本需要一起原子化执行的两个步骤分离开来,从而缩小了入队 /出队时需要原子化更新值的范围到唯一变量。这是非阻塞算法得以实现的关键。

    • 以批处理方式来更新head/tail,从整体上减少入队 / 出队操作的开销。

    二。文档说明摘要

    Iterators are weakly consistent, returning elements reflecting the state of the queue at some point at or since the creation of the iterator.

    They do not throw ConcurrentModificationException, and may proceed concurrently with other operations. Elements contained in the

    queue since the creation of the iterator will be returned exactly once.

    Beware that, unlike in most collections, the size method is NOT a constant-time operation. Because of the asynchronous nature of these

    queues, determining the current number of elements requires a traversal of the elements, and so may report inaccurate results if this collection

    is modified during traversal. Additionally, the bulk operations addAllremoveAllretainAllcontainsAllequals, and toArray are not 

    guaranteed to be performed atomically. For example, an iterator operating concurrently with an addAll operation might view only some of

    the added elements.

    相关内容:

    锁、volatile、CAS

    原文:Java并发编程(七)ConcurrentLinkedQueue的实现原理和源码分析

  • 相关阅读:
    RESTful API 设计最佳实践
    Linux给目录创建软链接的技巧
    KVM资源划分分配技巧
    SpringBoot无法启动,Process finished with exit code 0
    Shell中EOF内容转义
    TeamViewer运行在Windows Server 2008下连接时错误提示:正在初始化显示参数
    CentOS使用chkconfig增加开机服务提示service xxx does not support chkconfig的问题解决
    Redis哨兵模式主从同步不可以绑定127.0.0.1或者0.0.0.0,不然无法进行主从同步
    Spring Boot项目的Logback配置文件使用yaml格式
    Shell脚本里的双冒号是什么意思
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/7206570.html
Copyright © 2011-2022 走看看