• 锁、volatile、CAS 比较


    一。锁的劣势

       (1) 在JDK1.5之前都是使用synchronized关键字保证同步的,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有守

    护变量的锁,都采用独占的方式来访问这些变量

     (2)如果出现多个线程同时访问锁,则一些线程将被挂起,当线程恢复执行时,必须等待其它线程执行完他们的时间片以后才能被调度执行,在挂起和

    恢复执行过程中存在着很大的开销

     (3)当一个线程正在等待锁时,它不能做任何事

     (4)如果一个线程在持有锁的情况下被延迟执行,那么所有需要这个锁的线程都无法执行下去

     (5)如果被阻塞的线程优先级高,而持有锁的线程优先级低,将会导致优先级反转 

    二。volatile的优势

    (6)与锁相比,volatile变量是一和更轻量级的同步机制,因为在使用这些变量时不会发生上下文切换和线程调度等操作

    (7)volatile变量也存在一些局限:不能用于构建原子的复合操作,因此当一个变量依赖旧值时就不能使用volatile变量

    三。CAS操作

     (8) Compare and Swap,CPU指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的值更新为B,否则不修改并告诉V的值实际为多少”

     (9)CAS是乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂

    起,而是被告知这次竞争中失败。这种基于冲突检测的乐观并发策略,当线程数目非常多的情况下,失败的概率会指数型增加。

        public final int getAndIncrement() {
            for (;;) {
                int current = get();
                int next = current + 1;
                if (compareAndSet(current, next))
                    return current;
            }
        }

    四。JVM对CAS的支持

     (10)在JDK1.5中引入了底层的支持,在Integer,Long等类型上都公开了 CAS的操作,并且JVM把它们编译为底层硬件提供的最有效的方法,

    在运行CAS的平台上,运行时把它们编译为相应的机器指令,如果处理器不支持CAS指 令,那么JVM将使用自旋锁。

     (11)在CAS操作中,在更新之前先判断V的值是否仍然A,如果是的话就继续执行更新操作,但是有的时候还需要知道“自从上次看到V的值为A

    以后,这个值是否发生了变化”

     (12)解决方案:更新两个值:【引用,版本号】,即使这个值由A变为B,然后为变为A,版本号也是不同的。AtomicStampedReference更

    新一个“对象-引用”二元组,通过在引用上加上“版本号”,从而避免ABA问题,AtomicMarkableReference将更新一个“对象引用-布尔值”的二元 组。

    相关内容

    java原子类

    IBM系列: Java理论和实践

    正确使用volatile

  • 相关阅读:
    Semaphore类
    我的java学习之路五:java的循环和条件语句
    我的java学习之路四:java的基础类型和变量
    第一节 线性表
    我的java学习之路三:java的类与对象
    我的Java学习之路二:Java基础语法
    算法分析一:基本定义
    我的java学习之路一:java的安装以及环境配置
    【2019 CCPC 江西省赛】Cotree 树重心
    【2018 icpc 南京站】G
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/3991869.html
Copyright © 2020-2023  润新知