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

或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞的实现方式则可以使用循环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的实现原理和源码分析

ConcurrentLinkedQueue的更多相关文章

  1. 队列送券的实际应用--ConcurrentLinkedQueue并发队列

    1.TicketQueue.java--队列封装类,负责如下职责:a.把活动登记对象放入队列中b.从队列中获取活动登记对象,并派券 package com.datong.pear.ticket; im ...

  2. 【JUC】JDK1.8源码分析之ConcurrentLinkedQueue(五)

    一.前言 接着前面的分析,接下来分析ConcurrentLinkedQueue,ConcurerntLinkedQueue一个基于链接节点的无界线程安全队列.此队列按照 FIFO(先进先出)原则对元素 ...

  3. Java 线程 — ConcurrentLinkedQueue

    ConcurrentLinkedQueue 在考虑并发的时候可以先考虑单线程的情况,然后再将并发的情况考虑进来. 比如ConcurrentLinkedQueue: 先考虑单线的offer 再考虑多线程 ...

  4. Java多线程系列--“JUC集合”10之 ConcurrentLinkedQueue

    概要 本章对Java.util.concurrent包中的ConcurrentHashMap类进行详细的介绍.内容包括:ConcurrentLinkedQueue介绍ConcurrentLinkedQ ...

  5. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  6. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  7. 阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue

    LinkedBlockingQueue: public class LinkedBlockingQueue<E> extends AbstractQueue<E> implem ...

  8. CAS无锁算法与ConcurrentLinkedQueue

    CAS:Compare and Swap 比较并交换 java.util.concurrent包完全建立在CAS之上的,没有CAS就没有并发包.并发包借助了CAS无锁算法实现了区别于synchroni ...

  9. java线程控制、状态同步、volatile、Thread.interupt以及ConcurrentLinkedQueue

    在有些严格的系统中,我们需要做到干净的停止线程并清理相关状态.涉及到这个主题会带出很多的相关点,简单的总结如下: 我们知道,在java中,有一个volatile关键字,其官方说明(https://do ...

  10. java LinkedBlockingQueue和ConcurrentLinkedQueue的区别

    实现上看,两者都继承于AbstractQueue,但是ConcurrentLinkedQueue实现了Queue,而LinkedBlockingQueue实现了BlockingQueue,Blocki ...

随机推荐

  1. CentOS6.5下安装Oracle11g

    一.安装前系统准备 1. 修改主机名 #sed -i "s/HOSTNAME=localhost.localdomain/HOSTNAME=oracledb.01/" /etc/s ...

  2. 新唐ISP操作步骤(转)

    1,电脑上装上“NuMicro_ICP_Programming_Tool_v1.18.5320.zip”:2,把目标板通过SWD口的NU-LINK连接到电脑的USB口上:3,打开桌面的“NuMicro ...

  3. Git和GitHub入门基础

    -----------------------------------------//cd F:/learngit // 创建仓库git init  // 在当前目录下创建空的git仓库------- ...

  4. 敏捷开发中的Scrum流程和术语【转】

    任何人力流程都离不开人来执行,所以在讲解Scrum流程之前,有必要先把Scrum中的角色讲一下. 一天,一头猪和一只鸡在路上散步,鸡看了一下猪说,“嗨,我们合伙开一家餐馆怎么样?”,猪回头看了一下鸡说 ...

  5. C# - 获取类中属性的名称

    用反射控制的,不过获取属性名称的方法,用方法形式获取的,不知道消耗大不大 using System; using System.Collections.Generic; using System.Li ...

  6. c# MVC Take的使用

    Take的使用 myPicture = dbContext.MyPictures.Where(u => u.Width == request.Width && u.Height ...

  7. Writing Reentrant and Thread-Safe Code(译:编写可重入和线程安全的代码)

    Writing Reentrant and Thread-Safe Code 编写可重入和线程安全的代码 (http://www.ualberta.ca/dept/chemeng/AIX-43/sha ...

  8. python的高级特性:切片,迭代,列表生成式,生成器,迭代器

    python的高级特性:切片,迭代,列表生成式,生成器,迭代器 #演示切片 k="abcdefghijklmnopqrstuvwxyz" #取前5个元素 k[0:5] k[:5] ...

  9. docker报错“net/http: TLS handshake timeout”的解决方法

    为了永久性保留更改,您可以修改 /etc/docker/daemon.json 文件并添加上 registry-mirrors 键值. { "registry-mirrors": ...

  10. Docker 启动 Centos 镜像 提示"Error response from daemon: No command specified"

    奇怪的是当我执行启动其他的镜像的时候并没有报错,找了半天资料发现在启动centos这个镜像的时候需要在docker命令后面指定命令参数“/bin/bash”