悲观锁、乐观锁、自旋锁

悲观锁、乐观锁、自旋锁

(1)乐观锁

乐观锁是一种乐观的思想,即认为读多写少,遇到并发的可能性低,每次拿数据时都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用 版本号机制(或时间戳) 和 CAS 算法实现。

Java 中的乐观锁基本都是通过 CAS 操作实现的,CAS 是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。

–>缺点:

  • ABA问题:

CAS 会导致 “ABA 问题”。CAS 算法实现的一个重要前提是需要取出内存中某时刻的数据,而在下一时刻比较并替换,那么在这个时间差会导致数据的变化。

部分乐观锁的实现是通过版本号(version)的方式来解决 ABA 问题,乐观锁每次在执行数据的修改操作时,都会带上一个版本号,一旦版本号和数据的版本号一致就可以执行修改操作并对版本号执行 +1 操作,否则就执行失败,因为每次操作的版本号都会随着增加,所有不会出现 ABA 的问题。

  • 只能保证一个共享变量的原子操作

CAS 只对单个变量有效,但涉及到多个共享变量时 CAS 无效

(2)悲观锁
悲观锁就是悲观的思想,即认为写多,遇到并发的可能性高,每次拿数据时,都会认为别人会修改数据,所以在每次读数据的时候都会上锁,这样当别人想读写这个数据时就会阻塞,直到拿到锁。(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

Java 中的悲观锁就是 Synchronized,AQS 框架下的锁则是先尝试 CAS 乐观锁去获取锁,获取不到,才会转换为悲观锁,如 ReentrantLock

两种锁的使用场景
乐观锁适用于读多写少的情况,即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吐吞量。但如果是多写的情况下,一般会经常产生冲突,当获取锁失败时,就要不断的进行自旋操作以尝试重新获取锁,这样就会导致性能下降,所以一般多写的场景下用悲观锁就比较合适。

(3)自旋锁
自旋锁原理非常简单,如果持有锁的线程能在很短时间内释放锁资源,那么那些等待竞争锁资源的线程就不需要做内核态与用户态之间的切换进入阻塞挂起状态,它们只需要等一等(自旋),等待持有锁的线程释放锁后就可以立即获取锁,这样就避免用户态与内核态的切换消耗。

线程自旋是需要消耗 CPU 的,说白了就是让 CPU 在做无用功,如果一直获取不到锁,那线程也不能一直占用 CPU 自旋做无用功,所以需要设定一个自旋等待的最大时间。

优缺点:

自旋锁尽可能的减少线程的阻塞,这对于锁的竞争不激烈,且占用锁时间非常短的代码块来说性能大幅度的提升,因为自旋的消耗会小于线程阻塞挂起再唤醒的操作消耗,这些操作会导致线程发生两次上下文切换!

但是如果锁的竞争激烈,或持有锁的线程需要长时间占用锁执行同步块,这时候就不适合使用自旋锁了,因为自旋锁在获取锁前一直都是占用 CPU 做无用功,占着 XX 不 XX,同时有大量线程在竞争一个锁,会导致获取锁的时间很长,线程自旋的消耗大于线程阻塞的消耗,其它需要 CPU 的线程又不能获取到 CPU,造成 CPU 的浪费。所以这种情况下我们要关闭自旋锁。

深入理解CAS

public class casDemo {//CAS : compareAndSet 比较并交换public static void main(String[] args) {AtomicInteger atomicInteger = new AtomicInteger(2020);//boolean compareAndSet(int expect, int update)//期望值、更新值//如果实际值 和 我的期望值相同,那么就更新//如果实际值 和 我的期望值不同,那么就不更新System.out.println(atomicInteger.compareAndSet(2020, 2021));System.out.println(atomicInteger.get());//因为期望值是2020  实际值却变成了2021  所以会修改失败//CAS 是CPU的并发原语atomicInteger.getAndIncrement(); //++操作System.out.println(atomicInteger.compareAndSet(2020, 2021));System.out.println(atomicInteger.get());}
}

Unsafe 类

在这里插入图片描述

image-20200812220411463

总结:

CAS:比较当前工作内存中的值 和 主内存中的值,如果这个值是期望的,那么则执行操作!如果不是就一直循环,使用的是自旋锁。

缺点:

  • 循环会耗时;
  • 一次性只能保证一个共享变量的原子性;
  • 它会存在ABA问题

解决ABA问题,对应的思想:就是使用了乐观锁~------->带版本号的 原子操作
 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/352882.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

干货来啦!前端网站开发学什么内容?看这篇就足够了!

前端到底要学什么啊?分别有什么作用?今天好程序员带大家来认识一番。 首先前端这个词,它是fron end英文翻译过来的。front它有前面的意思,end它是端点的意思,合起来就是前端。理解起来就是给到用户面前他们能看到的东西…

upx-脱壳

发现是有壳的 先虚拟机脱壳 upx -d文件名 后分析代码如下 只要相等直接输出即为flag

LyScript 插件实现UPX脱壳

LyScript 插件可实现对压缩壳的快速脱壳操作,目前支持两种脱壳方式,一种是运用API接口自己编写脱壳过程,另一种是直接加载现有的脱壳脚本运行脱壳。 首先准备一个加了UPX压缩壳的程序,然后我们通过自己编写脚本完成脱壳任务。 我们…

DDCTF-re1-upx脱壳及去aslr

这道题目比赛时写的比较失败,壳用ESP定律没脱去,用脱壳机也没脱去。只好动态调试出结果。比赛结束后经过别的师傅们指导,了解了这题的脱壳方法。 使用linux进行脱壳命令 sudo apt-get install upx 安装脱壳机 之后输入命令upx -d re1.exe 发…

手动UPX脱壳演示

首先,用PEid打开加壳后的程序CrackmeUPX.exe,可以发现使用的是UPX壳。UPX壳是一种比较简单的压缩壳,只需要根据堆栈和寄存器的值进行调试,就能找到程序的正确入口点。当然,如果不怕麻烦的话,也可以全程单步调试&#x…

upx脱壳(手动)

1.upx脱壳几乎可以算是最简单的了,第一步还是查壳 2.第二步当然是od打开,提示解析代码,是和否都可以,然后f8,打硬件断点。 3.此时再f9执行到硬件断点,可以看到popad,壳代码到这基本上结束了&a…

upx脱壳日记

一、静态方法 upx -d 有时候可能会失败,需要切换使用正确的UPX版本。Windows下内置对各UPX版本的第三方图形化界面UPXShell工具,可以方便的切换版本,通过go按钮,可以切换upx加壳版本与脱壳版本 二、动态方法(手脱&am…

利用ESP定律的upx脱壳实践

背景: 除了命令行upx -d脱壳,还有手动脱壳。ESP定律的本质是堆栈平衡,又称堆栈平衡定律,是应用频率最高的脱壳方法之一,脱壳的目的就是找到真正的OEP(源文件的EP代码) 方法: 从push…

在线教育APP小程序系统开发 教培行业一站式解决方案

移动互联网如今已经深入到我们生活的方方面面,教育行业也不例外。如今市面上的在线教育APP小程序系统开发大受欢迎,很多学校、培训机构等都争相开发应用软件,以求通过全新的模式来满足不断扩大的市场需求,为用户提供更高质量的服务…

upx脱壳工具_攻防世界simple_unpack_逆向之旅003

攻防世界simple_unpack_逆向之旅003 前言一、使用exeinfo PE查看该文件二、使用upx脱壳三.使用ida打开脱壳处理后的文件总结 前言 先给出题目的链接: https://adworld.xctf.org.cn/task/answer?typereverse&number4&grade0&id5077&page1 题目说是…

[已发表,转载勘误]Android upx脱壳

已发在https://www.anquanke.com/post/id/197643 不过有部分内容发布之后无法编辑,勘误后如下。 Android upx脱壳 写在前面 因为我不是pc平台过来的,而是直接从Android入门的,所以upx壳其实一开始并不了解,后来接触到&#xff…

UPX压缩脱壳

该方法可针对 upx 变种,但Android Linker 的时候不需要section表, 所以我们不能修复 section 表 进行SO层代码脱壳 1. 使用IDA 打开libexec.so,在导出函数中找到.init_proc 函数(0x39A79), 搜索特征码7D 27 00 DF 搜索到下面语句 2.自己编译一个load程序 , 然…

UPX脱壳总结

我近期研究了一下UPX壳的脱壳方法,下面给出脱壳示例: UPX作为一款元老级PE加密壳,在以前的那个年代盛行,著名病毒【熊猫烧香】就是使用这款加密壳。 现在我们一起来脱UPX壳来揭开它的神秘面纱。 首先,PEiD载入含UPX壳…

记一次没遇到过的UPX脱壳

关于壳的介绍见CTF-WIKI 这里就不多赘述了 拿到我们的程序,先查看 64位upx壳,首先直接upx -d试一下,结果是失败报错提示下图 (一开始也有怀疑过是不是版本不兼容的问题,后来尝试高版本还是兼容低版本的) …

CTF逆向-Upx脱壳攻防世界simple unpack

文章目录 前言UPX技术原理应用范围软件使用 CTF实战程序查壳UPX脱壳 总结 前言 加壳软件分两类: 压缩壳:压缩的目的是减少程序体积,如 ASPack、UPX、PECompact 等;加密壳:加密是为了防止程序被反编译(反汇…

UPX脱壳逐一跟踪分析

UPX脱壳逐一跟踪分析 写在前面OD跟踪命令先结合PE知识分析分析“新年快乐.exe” 写在前面 之前看到的UPX脱壳文章都只是教了方法,对UPX的原理少有提及。看了《逆核》的UPX脱壳一章后,俺尝试把UPX脱壳与PE文件结构的知识结合起来整理了一些(也…

逆向:UPX脱壳

2020/05/18 - 引言 本身对加壳这种东西只是知道,只知道可以使用软件进行自动化脱壳,没有具体了解过原理。然后,最近部署的蜜罐经常下载UPX加壳的样本。这次就来分析一下。 学习到的东西 利用vim修改十六进制内容upx脱壳 样本 首先&#xff0c…

对于UPX脱壳的解决

(upx学习ing,不定期更新一些自己遇到的一些关于此的比较好的题目或者感悟) 对于手动脱壳,我们有两种常用的安全工具,一个是od,另一个是ida。两个方法略有不同。对于脱一般的程序壳的时候,我主要用的是ida来脱壳&#…

Linux4.9 Tomcat部署及优化

文章目录 计算机系统5G云计算第六章 LINUX Tomcat部署及优化一、Tomcat概述1.Tomcat核心组件2.什么是 servlet3.什么是 JSP4.Tomcat 功能组件结构5.Container 结构分析6.Tomcat 请求过程7. 配置文件 二、Tomcat 服务部署1.关闭防火墙,将安装 Tomcat 所需软件包传到/…

elf 变异upx 脱壳

题目 是某ctf题 首先使用IDA打开: 函数极少,有壳。 查看函数 这个跳转比较可疑 下面进行IDA动态调试 进入loc_52D516 再进入 直到找到jmp r13 运行到这里,F8跳转 直接retn下断点F9,直接retn下断点F9重复, 直到…