热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

乐观锁_乐观锁VS悲观锁

篇首语:本文由编程笔记#小编为大家整理,主要介绍了乐观锁VS悲观锁相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了乐观锁 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类理解的不够透彻,就进行使用的话,就等于给自己挖了无形之坑,最为致命。






推荐阅读
  • 超赞!GitHub上百万下载量Java面试手册!颠覆你的认知
    金三面试不顺心,马上银四面试在即,自己复盘总觉得Java知识点很凌乱?没有合适的方法学习!今天分享这份GitHub上百万下载量Ja ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • 讨伐Java多线程与高并发——MQ篇
    本文是学习Java多线程与高并发知识时做的笔记。这部分内容比较多,按照内容分为5个部分:多线程基础篇JUC篇同步容器和并发容器篇线程池篇MQ篇本篇 ... [详细]
  • 一段程序结束等待进行下一段程序_给你的Java程序拍个片子吧:jstack命令解析
    前言如果有一天,你的Java程序长时间停顿,也许是它病了,需要用jstack拍个片子分析分析,才能诊断具体什么病症ÿ ... [详细]
  • 网络模型_地铁时刻表建模之事件活动网络模型
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了地铁时刻表建模之事件-活动网络模型相关的知识,希望对你有一定的参考价值。 ... [详细]
  • python教程分享Pytorchmlu 实现添加逐层算子方法详解
    目录1、注册算子2、算子分发3、修改opmethods基类4、下发算子5、添加wrapper6、添加wrapper7、算子测试本教程分享了在寒武纪设备上pytorch-mlu中添加 ... [详细]
  • Zookeeper分布式过程协同技术部署及设置
    Zookeeper分布式过程协同技术-部署及设置Zookeeper支持单机模式、伪集群模式、集群模式三种部署方式。演示部署环境为CentOS、jdk版本为1.8、Zookeeper ... [详细]
  • Hadoop源码学习笔记(4)——Socket到RPC调用Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程。那这里如何让网络编程变得简单、透明的呢 ... [详细]
  • jdk8默认垃圾回收器_JVM系列之经典垃圾回收器(上篇)
    封面图1.前言随着JDK的不断更新,垃圾回收器的效率也越来越高。每一次JDK的更新,必然会包含有垃圾回收器的更新,截止目前, ... [详细]
  • Linux多线程(2)
    线程的知识点太多,太重要,所以分成三部分进行总结学习线程安全多个线程并发同一段代码时,不会出现不同的结果。常见对全局变量或者静态变量进行操作,并且没有锁保护的情况下,会出现该问题。 ... [详细]
  • Lock和synchronized该如何选择
    本文主要介绍关于Java,锁机制的知识点,对【【Java进阶】synchronized底层如何实现?什么是锁的升级、降级?】和【Lock和synchronized该如何选择】有兴趣的朋友可以看下由【刘 ... [详细]
  • JVMVisualVM学习
    使用VisualVM进行性能分析及调优WeiboGoogle用电子邮件发送本页面8概述开发大型Java应用程序的过程中难免遇到内存泄露、性能瓶颈等问题,比如文件、网 ... [详细]
  • 下载源码切换分支{代码}申明环境变量{代码}解决microbench工程编译问题报错信息{代码}解决办法批改pom.xml,显式援用jct包{代码}待续 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 详解Netty Zero Copy机制
    NettyZeroCopy的巧妙设计让Netty从众多高性 ... [详细]
author-avatar
G路过的彩虹
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有