浅谈Java非阻塞同步机制和CAS

 更新时间:2021年06月01日 12:59:08   作者:flydean  
我们知道在java 5之前同步是通过Synchronized关键字来实现的,在java 5之后,java.util.concurrent包里面添加了很多性能更加强大的同步类。这些强大的类中很多都实现了非阻塞的同步机制从而帮助其提升性能。

什么是非阻塞同步

非阻塞同步的意思是多个线程在竞争相同的数据时候不会发生阻塞,从而能够在更加细粒度的维度上进行协调,从而极大的减少线程调度的开销,从而提升效率。非阻塞算法不存在锁的机制也就不存在死锁的问题。

在基于锁的算法中,如果一个线程持有了锁,那么其他的线程将无法进行下去。使用锁虽然可以保证对资源的一致性访问,但是在挂起和恢复线程的执行过程中存在非常大的开销,如果锁上面存在着大量的竞争,那么有可能调度开销比实际工作开销还要高。

悲观锁和乐观锁

我们知道独占锁是一个悲观锁,悲观锁的意思就是假设最坏的情况,如果你不锁定该资源,那么就有其他的线程会修改该资源。悲观锁虽然可以保证任务的顺利执行,但是效率不高。

乐观锁就是假设其他的线程不会更改要处理的资源,但是我们在更新资源的时候需要判断该资源是否被别的线程所更改。如果被更改那么更新失败,我们可以重试,如果没有被更改,那么更新成功。

使用乐观锁的前提是假设大多数时间系统对资源的更新是不会产生冲突的。

乐观锁的原子性比较和更新操作,一般都是由底层的硬件支持的。

CAS

大多数的处理器都实现了一个CAS指令(compare and swap),通常来说一个CAS接收三个参数,数据的现值V,进行比较的值A,准备写入的值B。只有当V和A相等的时候,才会写入B。无论是否写入成功,都会返回V。翻译过来就是“我认为V现在的值是A,如果是那么将V的值更新为B,否则不修改V的值,并告诉我现在V的值是多少。”

这就是CAS的含义,JDK中的并发类是通过使用Unsafe类来使用CAS的,我们可以自己构建一个并发类,如下所示:

public class CasCounter {

    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
    private volatile int value;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                    (CasCounter.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    public CasCounter(int initialValue) {
        value = initialValue;
    }

    public CasCounter() {
    }

    public final int get() {
        return value;
    }

    public final void set(int newValue) {
        value = newValue;
    }

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

}

上面的例子中,我们定义了一个原子操作compareAndSet, 它内部调用了unsafe的compareAndSwapInt方法。

看起来上面的CAS使用比直接使用锁复杂,但实际上在JVM中实现锁定时需要遍历JVM中一条非常复杂的代码路径,并可能导致操作系统级的锁定,线程挂机和上下文切换等操作。在最好的情况下,锁定需要执行一次CAS命令。

CAS的主要缺点就是需要调用者自己来处理竞争问题(重试,回退,放弃),而在锁中可以自动处理这些问题。

前面的文章我们也讲到了原子变量,原子变量的底层就是使用CAS。

以上就是浅谈Java非阻塞同步机制和CAS的详细内容,更多关于Java非阻塞同步机制和CAS的资料请关注脚本之家其它相关文章!

相关文章

  • Java基于MySQL实现学生管理系统

    Java基于MySQL实现学生管理系统

    这篇文章主要为大家详细介绍了Java基于MySQL实现学生管理系统,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • MyBatis各种类型查询数据参数绑定的实现

    MyBatis各种类型查询数据参数绑定的实现

    本文主要介绍了MyBatis各种类型查询数据参数绑定的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • 如何在Spring中使用编码方式动态配置Bean详解

    如何在Spring中使用编码方式动态配置Bean详解

    这篇文章主要给大家介绍了关于如何在Spring中使用编码方式动态配置Bean的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • Idea如何查看Maven依赖树

    Idea如何查看Maven依赖树

    这篇文章主要介绍了Idea如何查看Maven依赖树问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04
  • Java实现飞机航班管理系统的思路详解

    Java实现飞机航班管理系统的思路详解

    这篇文章主要介绍了Java实现飞机航班管理系统的思路详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • mybatis in foreach 双层嵌套问题

    mybatis in foreach 双层嵌套问题

    这篇文章主要介绍了mybatis in foreach 双层嵌套问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Spring Cloud Eureka 注册与发现操作步骤详解

    Spring Cloud Eureka 注册与发现操作步骤详解

    这篇文章主要介绍了Spring Cloud Eureka 注册与发现操作步骤详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • SpringBoot接口数据加解密实战记录

    SpringBoot接口数据加解密实战记录

    现今对于大多数公司来说,信息安全工作尤为重要,下面这篇文章主要给大家介绍了关于SpringBoot接口数据加解密的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • JAVA IO的3种类型区别解析

    JAVA IO的3种类型区别解析

    这篇文章主要介绍了JAVA IO的3种类型解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Java框架解说之BIO NIO AIO不同IO模型演进之路

    Java框架解说之BIO NIO AIO不同IO模型演进之路

    网上很多IO资料,对新手来说,越看越晕。根据自己的理解,总结对比了一下BIO、NIO、AIO,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10

最新评论