美文网首页
乐观锁之CAS-ABA-Atomic-Unsafe

乐观锁之CAS-ABA-Atomic-Unsafe

作者: sizuoyi00 | 来源:发表于2019-11-29 02:26 被阅读0次

线程安全-非阻塞同步

互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题。随着硬件指令集的发展,有了另一个选择:基于冲突检测的乐观锁并发策略。先进行操作,如果没有其他线程争用共享数据,则操作成功;如果共享数据有争用,产生了冲突,那就采取其他的补充措施(最常见的就是不断地重试,直到成功为止)。这种乐观锁的并发策略不需要把线程挂起,因此这种同步操作称之为非阻塞同步

乐观锁实现前提

需要操作和冲突检测这两个步骤保证原子性,也就是只通过一条指令就能完成。
常见指令包括:

测试并设置(Test and Set)
获取并增加(Fetch and Increment)
交换(Swap)
比较与交换(Compare and Swap)
加载链接/条件存储(Load Linked/Store Conditional)

乐观锁实现-CAS

CAS对应底层cmpxchg指令,需要3个操作数,内存位置V,旧的预期值A,新值B。CAS指令执行时,当且仅当V符号预期值A时,处理器用新值B更新V的值,否则它就不执行操作。该过程是一个原子操作。

java程序中的CAS操作由sun.misc.Unsafe类里边的compareAndSwapInt()、sompareAndSwapLong()和compareAndSwapObject()等几个方法包装提供。
java-CAS方法参数:修改对象(内存位置),偏移量(该属性在对象(头文件)的哪个位置),原值,修改值。

cas一般与volatile配合使用,保证原子性,可见性。

ABA问题

如果一个变量V初次读取的时候是A值,并且在准备赋值的时候检查到它仍然为A值,那么就可以认定它的值没有被其他线程修改过吗?如果这段时间变量V的值中间被改为了B,后来又改回了A,那么CAS操作会误认为它从来没有被改变过。这个漏洞被称为"ABA"问题。
ABA发生的重点原因就是过程无法跟踪。

举例: 线程1拿到了a的值=1,线程2修改了a的值=2,然后做了一系列操作后,又恢复了a的值=1,这时线程1进行CAS操作发现没问题。

ABA问题解决

1.加版本概念,CAS除了比较值还要比较版本。
JUC提供了了AtomicStampedRefence类,通过控制变量值的版本来保证CAS的正确性。
2.改用传统的互斥同步。

Atomic

原子:不能被进一步分割的最小粒子
原子性:提供了互斥访问,同一时刻只能有一个线程对它进行操作
原子操作:不可被中断的一个或一系列操作
在atomic包里一共有12个类,Atomic包里的类基本都是使用Unsafe实现的包装类。
以AtomicInteger为例分析
内部结构

    // 反射获取魔术类Unsafe
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    // 偏移量  作为unsafe.CAS参数
    private static final long valueOffset;

    static {
        try {
            // 偏移量取值为value属性,在该对象文件头的内存位置
            valueOffset = unsafe.objectFieldOffset
                (AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }
    // 具体值
    private volatile int value;


    // CAS 当前值为预期值expect时,更新当前值为新值update
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

Unsafe使用

Unsafe不是提供给用户程序调用的类,Unsafe.getUnsafe()代码中限制了只有启动类加载器(Bootstrap ClassLoader)加载的Class才能访问它。
Unsafe引用方式
1.提供反射创建调用
2.通过java命令行把调用Unsafe的类所在包路径添加到默认boostrap包路径,使得该类被引导类加载器加载
sun.misc.Unsafe使用参考

相关文章

  • 乐观锁之CAS-ABA-Atomic-Unsafe

    线程安全-非阻塞同步 互斥同步最主要的问题就是进行线程阻塞和唤醒所带来的性能问题。随着硬件指令集的发展,有了另一个...

  • mysql 锁

    MySQL学习之——锁(行锁、表锁、页锁、乐观锁、悲观锁等)https://crossoverjie.top/ht...

  • 04 番外(待补充AQS相关原理) Java多线程中的各种锁

    1 乐观锁 悲观锁 1.1 乐观锁 乐观锁( Optimistic Locking ) 相对悲观锁而言,乐观锁假设...

  • CAS 与原子操作

    乐观锁与悲观锁 锁可以从不同的角度分类。其中,乐观锁和悲观锁是一种分类方式。 乐观锁:乐观锁又称为“无锁”。乐观锁...

  • MS-关于锁(乐观锁,悲观锁,行锁、表锁,共享锁,排他锁)

    这几个锁按照属性可分为:乐观锁、悲观锁(共享锁,排他锁),行锁、表锁指的是锁粒度。 乐观锁乐观锁就是很乐观的认为,...

  • 乐观锁与悲观锁——解决并发问题

    这几个锁按照属性可分为:乐观锁、悲观锁(共享锁,排他锁),行锁、表锁指的是锁粒度。 乐观锁乐观锁就是很乐观的认为,...

  • Mysql锁

    按照使用方式,锁分为: 悲观锁 乐观锁 乐观锁 概念就不细讲了,乐观锁和悲观锁的区别是乐观锁是假设在修改数据之前,...

  • 乐观锁和悲观锁

    参考来源 深入理解乐观锁与悲观锁 乐观锁的一种实现方式——CAS mysql乐观锁总结和实践 乐观锁和悲观锁 悲观...

  • 看完你就明白的锁系列之自旋锁

    看完你就明白的锁系列之自旋锁 在上一篇文章 看完你就应该能明白的悲观锁和乐观锁中我们已经学习到了什么是悲观锁和乐观...

  • 看完你就知道的乐观锁和悲观锁

    看完你就知道的乐观锁和悲观锁 Java 锁之乐观锁和悲观锁 [TOC] Java 按照锁的实现分为乐观锁和悲观锁,...

网友评论

      本文标题:乐观锁之CAS-ABA-Atomic-Unsafe

      本文链接:https://www.haomeiwen.com/subject/tqnrwctx.html