常见锁策略_CAS(Compare And Swap)_synchronized优化

synchronized 和 CAS synchronized 加锁过程、优化过程,CAS 阅读详情

目录

1.常见锁策略

1.1乐观锁vs悲观锁

1.2轻量级锁vs重量级锁

1.3自旋锁vs挂起等待锁

自旋锁

挂起等待锁

1.4互斥锁vs读写锁

1.5公平锁vs非公平锁

公平锁

非公平锁

1.6可重入锁vs不可重入锁

1.7使用锁策略描述synchronized

2.CAS(Compare And Swap)

2.1CAS应用场景

实现原子类

实现自旋锁

2.2CAS的ABA问题

3.synchronized原理

3.1锁升级/锁膨胀

无锁

偏向锁

轻量级锁

重量级锁

3.2锁消除

3.3锁粗化


1.常见锁策略

锁策略不仅仅局限于java,任何与"锁"相关的话题(操作系统,数据库...),都会涉及到锁策略,这些策略是给锁的实现者用来参考的

1.1乐观锁vs悲观锁

这个不是两把具体的锁.而是两类锁,是在锁冲突的概率上进行区分的

乐观锁指的是预测锁竞争不是很激烈(做的工作相对少一些),悲观锁预测锁竞争会很激烈(这里做的工作会多一些).

1.2轻量级锁vs重量级锁

是从锁开销的角度区分的

轻量级锁加锁解锁开销比较小,效率更高.重量级锁加锁解锁开销比较大,效率更低.

多数情况下,乐观锁也是一个轻量级锁,悲观锁也是一个重量级锁

1.3自旋锁vs挂起等待锁

自旋锁是典型的轻量级锁

挂起等待锁是典型的重量级锁]

自旋锁

自旋锁伪代码:

while (抢锁(lock) ==失败) {}

自旋锁如果获取锁失败,立即再尝试获取锁,无限循环..一旦锁被其他线程释放,就能第一时间获取到锁

自旋锁的优点:
没有放弃cpu,不涉及线程阻塞和调度,一旦锁被释放,就饿能第一时间获取到锁
缺点:
如果锁被其它线程持有的时间较长,那么就会持续的消耗cpu资源(挂起等待是不需要消耗资源的)

挂起等待锁

挂起等待锁:如果一个锁被另外的线程持有,挂起等待锁会一直等待,不会主动去获取锁

这种做法不会消耗大量cpu资源,就可以做别的工作了.

1.4互斥锁vs读写锁

互斥锁

提供加锁和解锁操作,就像我们使用过的synchronized这样的锁.如果一个线程加锁了,另一个线程也尝试获取锁,就会阻塞等待

读写锁

提供了三种操作

1.针对读加锁
2.针对写加锁
多线程针对同一个变量并发读是没有线程安全问题的.也不需要加锁.
读锁和读锁之间没有互斥
写锁和写锁之间是互斥的
写锁和读锁之间存在互斥
假设一组线程并发读同一个变量,这时线程之间是没有锁竞争的,也没有线程安全问题!假设一组线程有读又有写,才会产生锁竞争..实际开发中,读操作非常高频

3.解锁

1.5公平锁vs非公平锁

公平锁

把公平锁定义为"先来后到"

B比C先来获取锁然后阻塞等待的,当A释放锁之后,B就能先于C获取到锁

非公平锁

不遵守"先来后到"

不管BC谁先来的,当A释放锁之后,BC都有可能获取到锁,synchronized就是非公平锁!

操作系统内部的线程调度就是随机的,如果不做额外的限制,锁就是非公平锁,如果要实现公平锁,就需要额外的数据结构来保存先后顺序
公平锁和非公平锁没有优劣,要看适用的场景

1.6可重入锁vs不可重入锁

不可重入锁:一个线程针对同一把锁,连续加锁两次,出现死锁

可重入锁:一个线程针对同一把锁,连续加锁多次都不会出现死锁

1.7使用锁策略描述synchronized

上述种锁策略,就像是锁的形容词.任何一个锁,都能用上述锁策略来描述,形容,我们看synchronized是怎样的

1.synchronized既是一个悲观锁,又是个乐观锁
synchronized默认是乐观锁,但是如果发现锁竞争比较激烈,就会变成悲观锁!!
2.synchronized既是轻量级锁,又是一个重量级锁
synchronized默认是轻量级锁,当锁冲突剧烈后,就变成重量级锁!
3.synchronized这里的轻量级锁是基于自旋锁的方式实现的
synchronized这里的重量级锁是基于挂起等待锁的方式实现的
4.synchronized不是读写锁
5.synchronized是非公平锁
6.synchronized是可重入锁

2.CAS(Compare And Swap)

一个CAS涉及到以下操作:

我们假设内存中的原数据V,旧的预期值A,需要修改的新值B
1.比较A与V是否相等
2.如果相等,将B写入V
3.返回操作是否成功

上述交换过程中,大多数不关心B后续的情况了,更关心的是V这个变量的情况.近似可以理解成赋值了

如果AV不同,则没有其他操作

我们看一下CAS的伪代码:

boolean CAS(V,A,B){
    if(A == V){
        V = B;
        return true;
    }
    return false;
}
但是CAS的过程并非是通过代码实现的!!而是通过一条CPU指令完成的!CAS操作是原子的,因此它是线程安全的.那么解决线程安全问题除了加锁,就又有个新的思路了.
CAS是CPU提供的一个特殊指令,通过这个指令,就可以一定程度的处理线程安全问题!

2.1CAS应用场景

实现原子类

Java标准库中提供的有原子类,之前我们学习线程安全时,写过一个问题,两个线程对同一个变量进行自增操作后,这个变量没有达到预期的结果,我们是通过加锁解决线程安全问题的.这里我们直接使用原子类,就不会出现线程安全问题

        AtomicInteger count = new AtomicInteger();

AtomicInteger是原子类,基于CAS实现了自增,自减等操作,此时进行自增等操作不需要加锁,也线程安全的

public class Test {
    public static void main(String[] args) throws InterruptedException {
        //使用原子类解决线程安全问题
        AtomicInteger count = new AtomicInteger();
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                count.getAndIncrement();
            }
        });
        Thread t2 = new Thread(()->{
            for (int i = 0; i < 50000; i++) {
                count.getAndIncrement();
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(count);
    }
}

结果:

我们看一下伪代码实现的原子类

class AtomicInteger {
    private int value;
    public int getAndIncrement() {
        int oldValue = value;
        while ( CAS(value, oldValue, oldValue+1) != true) {
            oldValue = value;
       }
        return oldValue;
   }
}

这里的oldValue可以理解为是寄存器中的值,相当于先把内存中的值读到寄存器里

正常情况下,oldValue应该是和value的值是相同的,然后这里发生CAS,把old Value+1写到value中

但是也可能会有:执行完读取value到寄存器中后,线程切换了,另外一个线程也修改了内存中value的值,此时这个线程如果继续执行进行CAS判定,就会认为value和oldValue不相等了

value和oldValue不相等,然后重新读取oldValue

我们画图解释一下这个过程:

按照这个时间执行两个线程

t1,t2都进行加载

然后t2开始CAS

比较oldValue和value的值,发现相等,oldValue+1赋给value

t2线程执行完毕,切换回t1线程,t1线程开始CAS,发现oldValue和value的值不相等,返回false,不进行任何交换...然后进入循环,循环内部重新读取value的值到oldValue 中,此时再次比较,发现相等了,进行CAS操作,并返回true,循环结束

原子类这里的实现,每次修改之前都会再确认一下这个值是否符合要求

CAS是属于特殊方法,特定场景能使用,加锁操作是通用方式,各种场景都能使用,打击面很广!

实现自旋锁

我们看一下自旋锁的伪代码

public class SpinLock {
    private Thread owner = null;
    public void lock(){
        // 通过 CAS 看当前锁是否被某个线程持有.
        // 如果这个锁已经被别的线程持有, 那么就自旋等待.
        // 如果这个锁没有被别的线程持有, 那么就把 owner 设为当前尝试加锁的线程.
        while(!CAS(this.owner, null, Thread.currentThread())){
       }
   }
    public void unlock (){
        this.owner = null;
   }
}
Thread owner是记录当前锁是谁加的
this.owner是检测当前的owner是否是null,如果是null的,就进行交换,也就是把当前的线程的引用赋值给owner.如果赋值成功,此时循环结束,加锁完成!
如果当前锁已经被别的线程占用了,那么owner就不是null的,那么CAS就不会产生赋值,同时返回false,循环继续执行,进行下次判断,这就完成了自旋过程!!

在Java中,并不是直接提供了一个方法CAS.此处伪代码是便于理解

2.2CAS的ABA问题

CAS在运行中的核心是检查oldValue和value是否一致,如果一致,就认为value中途没有被修改过.所以进行下一步操作是没问题的

但是还有可能是中途被修改过,然后又还原回来了.把value值设为A,CAS判定value为A,此时value确实可能始终是A,也有可能本来是A,然后被修改为B,最后又还原成了A!这就是ABA问题

ABA情况大部分是不会对代码/逻辑产生太大影响的,当然也有极端情况,我们看下面这个情景:

如果ATM取钱使用的是CAS来扣款,假设A的账户余额1000,要取500.当按下取款按键时,机器卡顿了,A没忍住多按了几下,此时就会产生bug,可能出现重复扣款的现象

正常情况下,机器卡顿多按两次,t1线程的CAS发现余额是1000,然后就交换成500.扣款成功,然后t2线程加载时余额也是1000,CAS发现余额不是1000,就不扣款.正确的逻辑

下面这种情况,当t2执行CAS的时候,正好有人给A转入了500.那么余额就变成1000了, 执行CAS操作,又扣了500,出现了bug!!

当然这种情况出现的概率是很低的,但是还是可能出现,针对这种情况,采取的解决方案就是加入一个版本号,初始版本号是1,每次修改版本号都加1,然后进行CAS的时候,不是以金额多少为准了,是以版本号为准,此时如果版本号没变,就一定没有发生改变

3.synchronized原理

两个线程针对同一个变量加锁,就会阻塞等待.除了上述基本原理,synchronized还有一些内部的优化机制,存在的目的就是为了让锁更高效,好用.

3.1锁升级/锁膨胀

当执行到加锁的代码块儿时,加锁过程就可能经历下面几个升级阶段

无锁

无锁状态,还没开始加锁

偏向锁

进行加锁的时候,首先会进入偏向锁状态

偏向锁,并不是真正的加锁,而只是先占个位置,如果有需要就加锁,没需要就不加锁了

相当于"懒汉模式"提到的懒加载一样,非必要,不加锁

synchronized加锁的时候,并不是真正的加锁,而是先进入偏向锁状态,就相当于做一个标记,如果一直没有别的线程来获取这个锁,那么就不会升级,仅仅只做个标记,因为这个变量本来就只有这个线程要使用,过程也没有出现锁竞争,执行完synchronized{}代码块后,再取消掉标记(偏向锁)即可
但是如果出现了锁竞争,再另一个线程加锁之前,偏向锁会迅速升级为真正的加锁状态!!另一个线程阻塞等待...

轻量级锁

当synchronized发生锁竞争的时候,就会从偏向锁升级为轻量级锁(自旋锁)

此时,synchronized是通过自旋的方式来进行加锁的(就和刚刚伪代码一样的逻辑)

但是,如果很快就释放锁了,自旋是值得的,可以立即获取被释放的锁,反之,迟迟不被释放,那么久迟迟拿不到锁,自旋就不划算了..这时候就需要再次升级了!

重量级锁

一直自旋但是又拿不到锁,synchronized也不会无止境的自旋,此时升级为重量级锁(挂起等待锁)

重量级锁(挂起等待锁)则是基于操作系统原生的API来进行加锁了

linux原生提供了mutex一组API,操作系统北河提供的加锁功能,这个锁是会影响到线程的调度的

此时,如果线程进行了重量级锁的加锁,并且发生了锁竞争,此时线程就会被放入阻塞队列中,暂时不参加CPU的调度了,直到锁被释放了,这个线程才有机会被调度到并有机会获取到锁

锁升级了就不能降级了

3.2锁消除

这是编译器的智能判定,看当前代码是否真的需要加锁,如果这个场景不用加锁,就会自动把加的锁销毁

就像StringBuffer中的关键的方法都是带有synchronized修饰的,就不需要程序员再加锁,加了编译器也会自动销毁!

3.3锁粗化

锁的粒度:synchronized包含的代码越多,粒度就越粗.包含的代码越少,粒度就越细.

通常情况下,粒度细一点比较好,加锁的代码是不能并发执行的,锁的粒度越细,能并发的代码就越多,粒度越粗,能并发的越少.

有些情况,粒度粗反而更好

这种情况下,两次加锁解锁之间的间隙非常小,反反复复加锁解锁效率低开销大,可以直接加一个大锁,将间隙也包括,效率反而高些,毕竟间隙很小,这块儿代码能不能并发执行影响不大!

STM32智能头盔DIY全攻略:从心率监测到跌倒报警的完整实现 本文提供了基于STM32的智能头盔完整DIY实现方案,涵盖从心率监测到跌倒报警的核心功能。详细解析了系统设计、硬件搭建、软件算法及系统联调,重点介绍了STM32主控、MAX30102心率传感器和MPU6050姿态传感器的应用,并分享了跌倒检测算法与功耗优化等实战经验,为嵌入式开发与物联网创新项目提供全面指导。 阅读详情

相关推荐

SAP SD POD 配置与 VLPOD 操作:3步解决发货10件开票7件的业务场景

本文详细解析了SAP SD POD功能在解决发货与开票数量差异中的应用,通过3步配置法实现精准匹配。重点介绍了POD核心逻辑、关键配置步骤及VLPOD操作技巧,帮助企业高效处理易损品运输等复杂场景,提升供应链管理效率。

weixin_30613343的博客 396

【并发编程】 --- Compare And Swap(CAS)原理分析

文章目录1 什么是CAS?1.1 加锁和CAS解决原子性问题的不同原理1.2 CAS原理分析2 CAS可能的问题2.1 ABA问题2.2 循环时间长开销大2.3只能保证一个共享变量的原子操作3 JDK中的相关原子操作类简介 --- 底层CAS机制3.1 AtomicInteger3.2 AtomicIntegerArray3.3更新引用类型3.4 原子更新字段类4 源码地址:https://g...

nrsc 1万+

保姆级教程:用Cadence Sigrity Power DC搞定HI3516A板卡电源压降仿真(含常见报错解决)

本文提供了一份详细的Cadence Sigrity Power DC直流压降仿真教程,特别针对HI3516A板卡设计。从环境准备、器件建模到仿真执行和结果解读,全面覆盖了电源完整性分析的关键步骤,并提供了常见报错的解决方案,帮助工程师快速掌握直流压降分析技术。

weixin_42569329的博客 323

CAS(Compare-and-Swap)详解

本文主要介绍了Java中的CAS的相关知识,包括乐观锁和悲观锁、CAS的概念与原理、CAS与原子操作、CAS的三大问题以及CAS的应用场景。

专注Java和MySQL领域知识分享 1217

已过tiktok校招客户端,面经分享

面试的话, 一天面完3面, 效率很高, 三天之后就发了offer 字节邮件里面也说了不能泄露面试题, 那我就把我秋招参与美团,字节,腾讯,阿里面试被问到的全部问题总结着写出来了, 这其实是我每一轮面试完之后我都会总结哪里答对了, 哪里没有答对, 总结了一大堆问题出来. 答案未必正确, 我只是给自己写了个简单的一句话概括, 可能不够完善, 建议看官自行回答一下这些问题 二本非科班, 暑假在字节实习过, 不过不是tiktok部门, 因此秋招就没啥时间准备面试了, 只投了几个大厂, 顺便也在字节跨部门转正,

a1472750149的博客 1308

QNX Neutrino 进程间通信编程之Message-passing/Pulse

Interprocess Communication(IPC,进程间通信)在QNX Neutrino从一个嵌入式实时系统向一个全面的POSIX系统转变起着至关重要的作用。IPC是将在内核中提供各种服务的进程内聚在一起的粘合剂。在QNX中,消息传递是IPC的主要形式,也提供了其他的形式,除非有特殊的说明,否则这些形式也都是基于本地消息传递而实现的。本篇幅主要讲解Message-passing和Pulse。

zhuwade的博客 3533

乐观锁的实现之cas(Compare and Swap)

CAS(Compare and Swap)操作是一种并发编程中常用的原子操作,用于实现多线程环境下的无锁同步。CAS操作可以实现对共享变量的原子性读取和更新。CAS操作包括三个操作数:内存地址(或者说是变量的引用)、当前期望的值和新值。CAS操作的执行过程如下:1. 读取内存地址的当前值。2. 检查当前值是否与期望的值相等。3. 如果相等,将新值写入内存地址;否则,放弃操作。在执行CAS操作时,如果当前值与期望的值相等,说明在读取到值后没有其他线程修改过该值。

weixin_41973878的博客 897

VASP能带计算避坑指南:从CHGCAR读取失败到成功解决的全过程

本文深度解析VASP能带计算中常见的“CHGCAR读取失败”报错,并提供从静态自洽到非自洽计算的全流程避坑指南。核心解决方案包括使用CONTCAR替代POSCAR、调整SYMPREC参数以处理对称性判定问题,并推荐利用vaspkit工具自动化生成输入文件,确保计算流程稳健高效。

weixin_29245767的博客 772

CAS(Compare And Swap)

LongAddr 类是 LongAccumulator 类的一个特例,只是 LongAccumulator 提供了更强大的功能,可以自定义累加规则,当accumulatorFunction 为 null 时就等价于 LongAddr。当一个主线程获取主内存值时,该内存值在写入主内存时已经被修改了 N 次,但是最终又改成原来的值,比如其他线程先把 A 改成 B 又改回 A,主线程使用CAS操作。执行的是循环操作,如果比较不成功一直在循环,最差的情况某个线程一直取到的值和预期值都不一样,就会无限循环导致饥饿,

学习总结 1528

SAP-ABAP:SAP创建CDS视图(SQL语句创建)实例详解

通过Eclipse和ADT创建CDS视图是SAP开发中的一项重要技能。CDS视图不仅简化了数据建模,还提供了高性能和灵活性。掌握CDS视图的开发和使用,可以帮助你更好地支持SAP S/4HANA和Fiori应用的开发。

baidu_35680696的博客 1825

PCL 点云加权均值收缩

PCL 点云加权均值收缩

dayuhaitang1的博客 689

CAS和悲观锁的区别

CAS和悲观锁的区别

林隐的博客 995

Yolov8轻量级网络:Ghostnet、G_ghost、Ghostnetv2家族大作战(一):华为Ghostnet,超越谷歌MobileNet | CVPR2020

Yolov8引入轻量级网络Ghostnet、G_ghost、Ghostnetv2等,减少最新的深度神经网络的计算成本,引入高效的神经网络结构。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 2568

JavaWeb语法五:锁策略以及CAS

常见的锁策略,以及CAS,CAS中的ABA问题和它的解决办法。

qq_56701924的博客 959

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

多线程进阶(上)

多线程进阶

qq_774952435的博客 437

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)

文章总结了面试中有关多线程的考点,主要涉及锁的策略、synchronized中锁的升级,锁消除,锁粗化的过程以及CAS(Compare and swap)比较并交换,并引申出CAS的ABA问题,以及对应的解决方案。

Hacynn的博客 1689

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

多线程之四(锁策略+CAS+synchronized)

CAS的ABA问题 只要有一个记录,能够记录上 内存 中数据的变化,就可以解决ABA的问题了 记录就是 另外搞一个内存,保存M的“修改次数”(版本号)或者是“上次修改时间”通过这个方法,就可以解决ABA问题 synchronized加锁的具体过程 (1)偏向锁 (2)轻量级锁 (3)重量级锁 synchroized更多的是考虑降低程序员使用负担,所以内部就实现了“自适应”的操作

m0_58761900的博客 2014

CAS 的使用场景 & CAS的ABA问题的优化 以及 synchronized 的三大优化

CAS(Compare-And-Swap),是比较和交换的意思,它是一条CPU并发原语,用于判断内存中某个位置的值是否为预期值,如果是则更改为新的值,这个过程是原子的.它包含了三个参数:V,A,B。V表示要读写的变量内存地址A表示旧的预期值B表示准备设置的新值。

qq_62949535的博客 6409

线程常见锁策略,以及CAS相关内容

目录 1.线程常见锁策略 2.CAS 2.1基于CAS实现的"原子类" 2.2基于CAS实现的"自旋锁" 2.3CAS中的ABA问题 3.synchronized中锁的优化机制 1.线程常见锁策略 ①什么是锁策略: 接下来讲解的锁策略不仅仅是局限于 Java . 任何和 "锁" 相关的话题, 都可能会涉及到以下内容。这些特性主要是给锁的实现者来参考的。 ②乐观锁和悲观锁: 乐观锁: 预期锁冲突很低,做的更少,成本更低,更高效的操作 悲观锁: 预期锁冲突很高,做得更多,成本更高,

weixin_58850105的博客 1023

多线程(进阶)——常见锁策略+CAS+Synchronized优化过程

目录🥝常见锁策略🥝悲观锁和乐观锁🥝 重量级锁和轻量级锁🥝挂起等待锁和自旋锁🥝读写锁和普通的互斥锁🥝公平锁和非公平锁🥝可重入锁和不可重入锁🥝 Synchronized与锁策略之间的联系🍉CAS 🥝常见锁策略 锁策略和我们这样普通的程序猿基本无缘,和实现锁的人才才有关系. 这里提到的锁策略,和我们学的Java本身没什么关系,适用于所有和锁相关的情况 🥝悲观锁和乐观锁 悲观锁:预期锁冲突的概率很高; 乐观锁:预期锁冲突的概率很低; 锁冲突即是锁竞争,多个线程对一把锁的竞争 我们举个🌰 :现在疫情很严重,高

weixin_48796138的博客 1488

锁策略, cas 和 synchronized 优化过程

1.1 常見的鎖策略 預測鎖衝突概率 樂觀鎖:加鎖的時候,假設出現鎖衝突的概率不大。圍繞加鎖做的工作會更少。 悲觀鎖:加鎖的時候,假設鎖出現衝突的概率很大。圍繞加鎖做的工作會更多。 synchronized “自適應” 初始是樂觀的。鎖衝突達到一定程度就會轉變爲悲觀的。 加鎖開銷(時間開銷) 重量級鎖 輕量級鎖 挂起等待鎖:悲觀鎖/重量級鎖的一種典型實現。讓出cpu資源,過一段時間通過其他途徑得知,再伺機而動。 自旋

m0_74893352的博客 644

操作系统——锁策略, cas和synchronized优化过程

锁策略, cas 和 synchronized 优化过程

xh1605004242的博客 899

锁的优化(偏向锁、轻量级锁、重量级锁,CAS)

为什么出现CAS? 我们知道synchronized关键字不论是实现同步方法还是同步代码块,都需要首先执行monitorenter获取到锁对象的监视器monitor,同一时刻只有一个线程可以获取到锁对象的monitor监听器,退出时需要执行monitorexit进行解锁。 monitor机制是JDK1.6之前synchronized(内建锁)底层原理,又称为JDK1.6重量级锁。线程的阻塞和唤醒均...

sophia__yu的博客 4228

多线程--锁策略 CAS Synchronized锁优化

目录锁策略1. 乐观锁和悲观锁2. 读写锁重量级锁和轻量级锁自旋锁 锁策略 1. 乐观锁和悲观锁 乐观锁: 对于同一个数据的并发操作, 乐观锁不认为数据发生修改, 并不会对数据进行加锁操作, 只有当提交数据更新的时候才会对数据是否产生并发冲突而进行检测. 悲观锁: 在并发同步的角度, 悲观锁认为对于同一个数据的并发操作, 它会认为数据是一定会发生修改, 哪怕没有被修改, 也会认为修改. 通过上面的理解, 可以看出乐观锁适合用于读操作, 悲观锁适合用于写操作. 乐观锁常常采用的是CAS算法,典型的例子就是原子

姜守威的博客 496

java多线程常见锁策略CAS机制

目录本节要点常见锁策略synchronized使用的锁策略CASCAS使用 本节要点 了解常见锁策略 了解synchronized使用的锁策略 理解CAS实现逻辑 了解CAS出现的ABA问题,并解决 synchronized锁的原理 常见锁策略 我们已经知道锁在我们的并发编程十分重要.那我们就需要了解,这些锁实现的策略!都有那些策略,便于我们更加深刻的理解锁! 下面介绍的几组锁策略,每一组里面都是相异的,每组策略之间又有相互关联的! 乐观锁 vs 悲观锁 这是程序员处理锁冲突的态度(原因),通过自己

bug郭的博客 795

java常见锁策略与CAS

ABA的问题假设存在两个线程t1和t2.。有一个共享变量num,初始值为A.接下来,线程t1想使用CAS把num值改成Z,那么就需要先读取num的值,记录到oldNum变量中。使用CAS判定当前num的值是否为A,如果为A,就修改成Z....

weixin_60778429的博客 701
上一篇: 多线程案例-线程池
下一篇: Callable接口_JUC的常见类_多线程环境使用ArrayList
YoLo♪
YoLo♪ 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄5年 1万+粉丝 174原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YoLo♪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值