017 无锁与CAS

一 . 概述

我们知道加锁会对多线程的并发有影响,那么我们是否有无锁的方式保证线程的安全性呢?有的,就是CAS方式.

  CAS的核心就是乐观的尝试,将线程的阻塞变成了线程的尝试,认为即使在不断尝试的代价也比阻塞后唤醒的代价要小.



二 CAS

CAS到底是什么呢? 其实就是一个JVM的指令,其中这个指令的执行是原子性的,也就是说不会被打断.

  我们看下AtomicInter的原子实现:  

    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

我们看到使用了unsafe完成了CAS操作,CAS代表的就是比较并且更新(交换).

    当现在的值等于期待值就会更新并且返回ture,

    不等于就会返回false,并且不会更新.

    public final int getAndUpdate(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return prev;
    }

我们看上述的JDK的实现,使用了一个while循环不断试探是否是线程安全的.

  我们知道while体内的操作可能不是安全的,也就是会发生修改修改,那么现在的值就和期待值不一致,那么CAS保证不去更新.

  循环就会再次尝试,知道成功为止.

  通过这种尝试的方式保证操作是线程安全的.



三 .ABA问题

我们知道,CAS不保证循环体的过程,但是保证结果是正确的,这也就是说循环体内

  可能发生了一个自减操作,然后又做出了一个自增操作,这种情况下,期待值和实际值确实是一致的,但是不能保证原子性了.

问题解决:

  解决的方式很简单,我们在原始的CAS之上加上一个时间戳,时间戳可以保证两次操作之间不应该有其它的操作.

  为此,出现了AtomicStampedReference这样的类可以保证线程安全.

原文地址:https://www.cnblogs.com/trekxu/p/8996782.html

时间: 2024-10-19 16:57:49

017 无锁与CAS的相关文章

无锁算法CAS 概述

无锁算法CAS 概述 JDK5.0以后的版本都引入了高级并发特性,大多数的特性在java.util.concurrent包中,是专门用于多线并发编程的,充分利用了现代多处理器和多核心系统的功能以编写大规模并发应用程序.主要包含原子量.并发集合.同步器.可重入锁,并对线程池的构造提供了强力的支持. 原子量是定义了支持对单一变量执行原子操作的类.所有类都有get和set方法,工作方法和对volatile变量的读取和写入一样.并发集合是原有集合框架的补充,为多线程并发程序提供了支持.主要有:Block

无锁机制下的原子性操作

通常使用volatile关键字修饰字段可以实现多个线程的可见性和读写的原子性,但是对于字段的复杂性操作就需要使用synchronize关键字来进行,例如: public class Counter { private volatile int count = 0; public synchronized int getAndIncr() { return this.count ++; } } 这里可以看到,对于字段的简单设置和获取,volatile可以应付,但是我们想每次获取后自增加1,这样的操

Java高并发之无锁与Atomic源码分析

目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntegerFieldUpdater 无锁的Vector 无锁即无障碍的运行, 所有线程都可以到达临界区, 接近于无等待. 无锁采用CAS(compare and swap)算法来处理线程冲突, 其原理如下 CAS原理 CAS包含3个参数CAS(V,E,N).V表示要更新的变量, E表示预期值, N表示新值.

Compare And Swap(CAS)实现无锁多生产者

1.CAS 原理 compare and swap,解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数--内存位置(V).预期原值(A)和新值(B).如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值.否则,处理器不做任何操作.无论哪种情况,它都会在CAS指令之前返回该位置的值.CAS有效地说明了"我认为位置V应该包含值A:如果包含该值,则将B放到这个位置:否则,不要更改该位置,只告诉我这个位置现在的值即可. 当同时存在读写线程时,默认情况下是不保证线

无锁编程:lock-free原理;CAS;ABA问题

转自:http://blog.csdn.net/kangroger/article/details/47867269 定义 无锁编程是指在不使用锁的情况下,在多线程环境下实现多变量的同步.即在没有线程阻塞的情况下实现同步.这样可以避免竞态.死锁等问题. 原理 CAS是指Compare-and-swap或Compare-and-Set CAS是一个原子操作,用于多线程环境下的同步.它比较内存中的内容和给定的值,只有当两者相同时(说明其未被修改),才会修改内存中的内容. 实现如下: int comp

无锁-CAS原子操作

CAS原子操作--Compare & Set,或是 Compare & Swap,现在几乎所有的CPU指令都支持CAS的原子操作,X86下对应的是 CMPXCHG 汇编指令. 大家应该还记得操作系统里面关于"原子操作"的概念,一个操作是原子的(atomic),如果这个操作所处的层(layer)的更高层不能发现其内部实现与结构.原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序是不可以被打乱,或者切割掉只执行部分.有了这个原子操作这个保证我们就可以实现无锁了. 相对

无锁同步-C++11之Atomic和CAS

1.概要 本文是无锁同步系列文章的第一篇,主要探讨C++11中的Atomic. 我们知道在C++11中引入了mutex和方便优雅的lock_guard.但是有时候我们想要的是性能更高的无锁实现,下面我们来讨论C++11中新增的原子操作类Atomic,我们可以利用它巧妙地实现无锁同步. 2.传统的线程同步 1 #include <thread> 2 #include <mutex> 3 4 #include <iostream> 5 6 using namespace s

4.锁--无锁编程以及CAS

无锁编程以及CAS 无锁编程 / lock-free / 非堵塞同步 无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被堵塞的情况下实现变量的同步,所以也叫非堵塞同步(Non-blocking Synchronization). 实现非堵塞同步的方案称为"无锁编程算法"( Non-blocking algorithm). lock-free是眼下最常见的无锁编程的实现级别(一共三种级别). 为什么要 Non-blocking sync ? 使用lock实现线程同步

CAS原子锁 高效自旋无锁的正确用法

1 #pragma once 2 #ifndef _atomic_lock_h_include_ 3 #define _atomic_lock_h_include_ 4 5 #include <windows.h> 6 7 #define cpu_pause() __asm {pause} 8 #define thread_yield() Yield() 9 10 #define spin_num (2048) 11 12 typedef struct { 13 volatile long l