一文秒懂Java中的乐观锁 VS 悲观锁

 更新时间:2021年05月06日 10:38:15   作者:小刘你最强  
这篇文章主要介绍了java乐观锁 VS 悲观锁的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

乐观锁 VS 悲观锁

悲观锁:总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。

乐观锁:总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改。
乐观锁在Java中通过使用无锁来实现,常用的是CAS,Java中原子类的递增就是通过CAS自旋实现。

在这里插入图片描述

CAS

CAS全称 Compare And Swap(比较与交换),是一种无锁算法。在不使用锁(没有线程被阻塞)的情况下实现多线程之间的变量同步。java.util.concurrent包中的原子类就是通过CAS来实现了乐观锁。

一个 CAS 涉及到以下操作:
我们假设内存中的原数据V,旧的预期值A,需要修改的新值B,

  1. 比较 A 与 V 是否相等。(比较)
  2. 如果比较相等,将 B 写入 V。(交换)
  3. 返回操作是否成功。

CAS的底层原理

  • 调用 Unsafe 类中的 CAS 方法,JVM 会帮我们实现出 CAS 汇编指令
  • 这是一种完全依赖于硬件的功能,通过它实现原子操作
  • 原语的执行必须是连续的,在执行过程中不允许被中断,CAS 是 CUP 的一条原子指令

CAS的三大问题

  • 如果 CAS 长时间一直不成功,会给 CPU 带来很大的开销,在Java的实现中是一只通过while循环自旋CAS获取锁。
  • 只能保证一个共享变量的原子操作
  • 引出了 ABA 问题

ABA问题

CAS需要在操作值的时候检查内存值是否发生变化,没有发生变化才会更新内存值。但是如果内存值原来是A,后来变成了B,然后又变成了A,那么CAS进行检查时会发现值没有发生变化,但是实际上是有变化的。

如何解决ABA问题
加入版本信息,例如携带 AtomicStampedReference 之类的时间戳作为版本信息,保证不会出现老的值。

UnSafe

Unsafe类是在sun.misc包下,不属于Java标准。但是很多Java的基础类库,包括一些被广泛使用的高性能开发库都是基于Unsafe类开发的,比如Netty、Cassandra、Hadoop、Kafka等。Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。

使用Unsafe可用来直接访问系统内存资源并进行自主管理,Unsafe类在提升Java运行效率,增强Java语言底层操作能力方面起了很大的作用。

Unsafe可认为是Java中留下的后门,提供了一些低层次操作,如直接内存访问、线程调度等。

这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率。但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的,它所分配的内存需要手动free(不被GC回收)。如果对Unsafe类理解的不够透彻,就进行使用的话,就等于给自己挖了无形之坑,最为致命。

到此这篇关于一文秒懂乐观锁 VS 悲观锁的文章就介绍到这了,更多相关java乐观锁 悲观锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis-Plus动态表名的使用

    MyBatis-Plus动态表名的使用

    本文主要介绍了MyBatis-Plus动态表名的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • java生成随机字符串的两种方法

    java生成随机字符串的两种方法

    这篇文章主要为大家详细介绍了java生成随机字符串的两种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-10-10
  • 浅谈Java Fork/Join并行框架

    浅谈Java Fork/Join并行框架

    这篇文章主要介绍了浅谈Java Fork/Join并行框架,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • java线程池中Worker线程执行流程原理解析

    java线程池中Worker线程执行流程原理解析

    这篇文章主要为大家介绍了java线程池中Worker线程执行流程原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Java判断IP地址为内网IP还是公网IP的方法

    Java判断IP地址为内网IP还是公网IP的方法

    这篇文章主要介绍了Java判断IP地址为内网IP还是公网IP的方法,针对tcp/ip协议中保留的三个私有地址进行判断分析,是比较实用的技巧,需要的朋友可以参考下
    2015-01-01
  • SpringBoot+Ant Design Vue实现数据导出功能方式

    SpringBoot+Ant Design Vue实现数据导出功能方式

    这篇文章主要介绍了SpringBoot+Ant Design Vue实现数据导出功能方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java 并发编程之ForkJoin框架

    Java 并发编程之ForkJoin框架

    这篇文章主要为大家介绍了Java ForkJoin框架,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助,希望能够给你带来帮助
    2021-11-11
  • SpringBoot之自定义Filter获取请求参数与响应结果案例详解

    SpringBoot之自定义Filter获取请求参数与响应结果案例详解

    这篇文章主要介绍了SpringBoot之自定义Filter获取请求参数与响应结果案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • Java编程实现获取当前代码行行号的方法示例

    Java编程实现获取当前代码行行号的方法示例

    这篇文章主要介绍了Java编程实现获取当前代码行行号的方法,结合实例形式分析了java基于StackTraceElement对象实现获取代码行号的相关操作技巧,需要的朋友可以参考下
    2017-08-08
  • MyBatis中的配置文件详解

    MyBatis中的配置文件详解

    在 MyBatis 中,配置文件分为 全局配置文件(核心配置文件)和映射配置文件,本文给大家介绍MyBatis中的配置文件相关知识,感兴趣的朋友一起看看吧
    2023-10-10

最新评论