看了下网上关于链表的无锁操作,写的不清楚,遂自己整理一部分,主要使用concurrent并发包的CAS操作。

1. 链表尾部插入

待插入的节点为:cur

尾节点:pred

基本插入方法:

do{

  pred = find_tail();              //重新找尾节点

}(! pred.next.compareAndSet(NULL, cur))  //pred.next 是否为NULL,是则将其指向cur,不是则有新的节点插入

这种插入方法是不带标记的,如果不涉及链表删除这个方法是可行的。

但是如果有删除操作,pred节点可能会被删除,所以我们需要再加入一个标记位判断pred是否被删除(false 未删除)

do{

  pred = find_tail();              

}(! pred.next.compareAndSet(NULL, cur, false, false));  //检查pred.next是被否标记为false,并标记为false

因为我们插入是对pred.next进行CAS操作,所以虽然要判断pred是否被删除,我们却只能看它的next域的标记,所以在删除的时候要和这里配合置next位为true让本次添加不成功

注意这里的next的置位与否不是next节点的,是pred本身的,因为只能从pred自己看到是否被删除,所以节点的数据结构不包含flag,节点的next域包含flag,这种结构具体参考AtomicMarkableReference

这里如果先判断pred是否为false是不行的,所有操作必须在CAS中完成,因为判断的一瞬间是OK的但是不代表执行CAS的时候也是OK的

(TIP:因为是队尾,next域是NULL,但是仍然含有标记位,每个新node尾节点添加的时候都是node.next = new AtomicMarkableReference<Node>(null,false))

2. 链表删除节点

待删除的节点为:cur

do{

  succ = cur.next;        //重新找next节点

  if (cur.next == true) break;   //有线程已经将其逻辑删除

  pred = pred(cur);       //找pred节点

  flag1 = cur.next.compareAndSet(succ, succ, false, true);  //第一个CAS将cur.next置为true,防止添加操作和重复删除操作

  if (! flag1) continue;

  flag2 = pred.next.compareAndSet(cur, succ, false, false);  //第二个CAS将pred.next指向succ,并将succ的为置为false

  if(! flag2) continue;

}(0);

这里两次CAS操作,第一次置位,也就是所谓的逻辑删除,和添加节点相呼应,这里标记完了之后在第二个CAS执行前,往本节点之后的添加都不成功

本次CAS失败说明有其它线程的删除操作或CAS之前有往cur的next有添加操作(succ改变),返回再次尝试

第二次则将原来指向cur的pred.next指向succ,进行物理删除,这里succ已经不能改变了,因为第一次CAS成功之后next置位其他线程既不能添加也不能删除

但是pred可以被删除,pred被删除之后导致pred.next置位,这次CAS失败。

这里第二次CAS操作可能其他地方也有相同的代码,如果本线程在第一次CAS调用完后阻塞,可以让其他线程看到这个标记后帮忙进行节点删除和清置位,这也是wait free的设计的核心思想

3. 链表某节点插入

实现原理相同,不多赘述,一定要注意和删除的判断过程是保证自洽的。

链表的无锁操作 (JAVA)的更多相关文章

  1. Atitit。Cas机制 软件开发 编程语言 无锁机制 java c# php

    Atitit.Cas机制 软件开发 编程语言 无锁机制 java c# php 1. 为什么需要无锁操作1 2. 硬件支持 cas  atomic2 3. 无锁编程(Lock-Free)就是在某些应用 ...

  2. 聊聊高并发(三十二)实现一个基于链表的无锁Set集合

    Set表示一种没有反复元素的集合类,在JDK里面有HashSet的实现,底层是基于HashMap来实现的.这里实现一个简化版本号的Set,有下面约束: 1. 基于链表实现.链表节点依照对象的hashC ...

  3. 无锁同步-JAVA之Volatile、Atomic和CAS

    1.概要 本文是无锁同步系列文章的第二篇,主要探讨JAVA中的原子操作,以及如何进行无锁同步. 关于JAVA中的原子操作,我们很容易想到的是Volatile变量.java.util.concurren ...

  4. CAS无锁操作

    https://coolshell.cn/articles/8239.html 主要讲的是<Implementing Lock-Free Queues>的论点,具体直接看论文最好.这里总结 ...

  5. 【Java并发编程】9、非阻塞同步算法与CAS(Compare and Swap)无锁算法

    转自:http://www.cnblogs.com/Mainz/p/3546347.html?utm_source=tuicool&utm_medium=referral 锁(lock)的代价 ...

  6. (转载)java高并发:CAS无锁原理及广泛应用

    java高并发:CAS无锁原理及广泛应用   版权声明:本文为博主原创文章,未经博主允许不得转载,转载请注明出处. 博主博客地址是 http://blog.csdn.net/liubenlong007 ...

  7. 非阻塞同步算法与CAS(Compare and Swap)无锁算法

    锁(lock)的代价 锁是用来做并发最简单的方式,当然其代价也是最高的.内核态的锁的时候需要操作系统进行一次上下文切换,加锁.释放锁会导致比较多的上下文切换和调度延时,等待锁的线程会被挂起直至锁释放. ...

  8. boost 无锁队列

    一哥们翻译的boost的无锁队列的官方文档 原文地址:http://blog.csdn.net/great3779/article/details/8765103 Boost_1_53_0终于迎来了久 ...

  9. DIOCP开源项目-Delphi高性能无锁队列(lock-free)

    最近想在DIOCP中加入任务调度线程,DIOCP的工作线程作为生产者(producer)将接受到的数据对象,投递到任务调度线程中,然后统一进行分配.然而这一切都需要一个队列, 这几天都在关注无锁队列. ...

随机推荐

  1. Android fragment切换后onresume时报 Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim'

    动态加载fragment以后,调用了remove方法移除Fragment,在返回来的时候报 Attempt to write to field 'int android.support.v4.app. ...

  2. highstaock+websocket实现动态展现

    效果:从后台获取回测数据,在前端动态展现,和聚宽实现的回测效果相仿 大体思路:先传一个[[int,0],[int,0],[int,0],[int,0],[int,0],...]格式的死数据到前端渲染x ...

  3. requests+正则表达式爬取ip

    #requests+正则表达式爬取ip #findall方法,如果表达式中包含有子组,则会把子组单独返回出来,如果有多个子组,则会组合成元祖 import requests import re def ...

  4. 处理异常、常用类、反射、类加载与垃圾回收、java集合框架

    异常处理概述 检查异常:检查异常通常是用户错误或者不能被程序员所预见的问题.(cheched) 运行时异常:运行时异常是一个程序在运行过程中可能发生的.可以被程序员避免的异常类型.(Unchecked ...

  5. git checkout+文件丢失

    坑:不知什么时候, 应该是初学git的时候, 在桌面git init了一下, 这次忘记切目录直接在桌面git checkout了, 导致文件丢失了. 解决: 简单复原: git reflog # 查看 ...

  6. 使Asp.net Core同时支持输出Json/Xml

    我们知道Asp.net Core是支持输出为Json格式的.同时也支持输出为xml格式.只要我们正确的配置.并在Request时指定正确的Accept,即可根据不同的Header来输出不同的格式. 前 ...

  7. Mac安装opencv指南

      最近接到了新的调研任务.主要是和人脸,各种所谓'AI'相关的.因为这里要处理视频和图像.于是在网上看到很多资料都是关于opencv的所以准备用opencv来开发这些东西.既然要用到opencv.那 ...

  8. 创建类似于Oracle中decode的函数

    -- 创建类似于Oracle中decode的函数create or replace function decode(variadic p_decode_list text[])returns text ...

  9. [LeetCode] Baseball Game 棒球游戏

    You're now a baseball game point recorder. Given a list of strings, each string can be one of the 4 ...

  10. ios开发-指纹识别

    最近我们使用支付宝怎么软件的时候,发现可以使用指纹了,看起来是否的高大上.当时苹果推出了相关接口,让程序写起来很简单哈. 在iPhone5s的时候,苹果推出了指纹解锁.但是在ios8.0的时候苹果才推 ...