synchronized与CAS(更新)

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

synchronized(重量级锁)

synchronized概念

原子性:synchronized保证语句块内操作是原子的
可见性:synchronized保证可见性(通过“在执行unlock之前,必须先把此变量同步回主内存”实现)
有序性:synchronized保证有序性(通过“一个变量在同一时刻只允许一条线程对其进行lock操作”)

synchronized原理

Java字节码层级:

synchronized(o) 

字节码层级:
使用javap -c Synchronize可以查看编译之后的具体信息。monitorenter指令插入到同步代码块的开始位置,monitorexit指令插入到同步代码块的结束位置,JVM需要保证每一个monitorenter都有一个monitorexit与之相对应。任何对象都有一个monitor(在对象头中)与之相关联,当且一个monitor被持有之后,他将处于锁定状态。线程执行到monitorenter指令时,将会尝试获取对象所对应的monitor所有权,即尝试获取对象的锁;
在这里插入图片描述
CPU汇编层级:lock comxchg


CAS(轻量级锁)

CAS概念

在这里插入图片描述

Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 (无重量锁),作用是保证多个线程对一个线程的更新。

CAS底层

自己写过的原子类:

        AtomicInteger i = new AtomicInteger();
        i.incrementAndGet();

点击incrementAndGet(),跳转到unsafe类:

    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }

发现调用了compareAndSwapInt方法。

    public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
        return var5;
    }

通过native实现,也是lock cmpxchg 指令。其中在硬件层级上lock指令在执行后面指令的时候锁定一个北桥信号。

ABA问题

其他线程修改数字值后,值与原值相同。
解决措施: 增加版本号或者boolean类型。


对象:

对象创建过程

在这里插入图片描述
①类加载检查: 虚拟机遇到⼀条 new 指令时,⾸先将去检查这个指令的参数是否能在常量池中定位到这个类的符号引⽤,并且检查这个符号引⽤代表的类是否已被加载过、解析和初始化过。如果没有,那必须先执⾏相应的类加载过程。

②分配内存: 在类加载检查通过后,接下来虚拟机将为新⽣对象分配内存。对象所需的内存⼤⼩在类加载完成后便可确定,为对象分配空间的任务等同于把⼀块确定⼤⼩的内存从 Java 堆中划分出来。分配⽅式有 “指针碰撞” 和 “空闲列表” 两种,选择那种分配⽅式由 Java 堆是否规整决定,⽽Java堆是否规整⼜由所采⽤的垃圾收集器是否带有压缩整理功能决定。

③初始化零值: 内存分配完成后,虚拟机需要将分配到的内存空间都初始化为零值(不包括对象头),这⼀步操作保证了对象的实例字段在 Java 代码中可以不赋初始值就直接使⽤,程序能访问到这些字段的数据类型所对应的零值。

④设置对象头: 初始化零值完成之后,虚拟机要对对象进⾏必要的设置,例如这个对象是那个类的实
例、如何才能找到类的元数据信息、对象的哈希吗、对象的 GC 分代年龄等信息。 这些信息存放在对
象头中。 另外,根据虚拟机当前运⾏状态的不同,如是否启⽤偏向锁等,对象头会有不同的设置⽅
式。

⑤执⾏ init ⽅法: 在上⾯⼯作都完成之后,从虚拟机的视⻆来看,⼀个新的对象已经产⽣了,但从
Java 程序的视⻆来看,对象创建才刚开始, ⽅法还没有执⾏,所有的字段都还为零。所以⼀
般来说,执⾏ new 指令之后会接着执⾏ ⽅法,把对象按照程序员的意愿进⾏初始化,这样
⼀个真正可⽤的对象才算完全产⽣出来。

对象的访问定位有哪两种⽅式

⽬前主流的访问⽅式有①使⽤句柄和②直接指针两种:
句柄: 如果使⽤句柄的话,那么Java堆中将会划分出⼀块内存来作为句柄池,reference 中存
储的就是对象的句柄地址,⽽句柄中包含了对象实例数据与类型数据各⾃的具体地址信息;
在这里插入图片描述
直接指针: 如果使⽤直接指针访问,那么 Java 堆对象的布局中就必须考虑如何放置访问类型
数据的相关信息,⽽reference 中存储的直接就是对象的地址。

在这里插入图片描述

堆内存中对象的分配的基本策略

堆空间的基本结构:
在这里插入图片描述
上图所示的 eden区、s0区、s1区都属于新⽣代,tentired 区属于⽼年代。⼤部分情况,对象都会⾸先在 Eden 区域分配,在⼀次新⽣代垃圾回收后,如果对象还存活,则会进⼊ s0 或者 s1,并且对象的年龄还会加 1(Eden区i>Survivor 区后对象的初始年龄变为1),当它的年龄增加到⼀定程度(默认为15岁),就会被晋升到⽼年代中。对象晋升到⽼年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold 来设置。
另外,⼤对象和⻓期存活的对象会直接进⼊⽼年代。
在这里插入图片描述

对象内存布局

对象头(markwoed8字节,类型指针4字节) 实例数据0字节 对齐位 4字节,其中类型指针压缩时占用4字节(JVM默认开启),关闭时占用8字节。
在这里插入图片描述
问下面对象头占多少字节?16个字节,如果算上引用类型b还是16个字节,因为对齐位为0。

Object b = new Object();

对象头hotspot实现

对象头里面有锁状态信息、GC信息、hashCode
在这里插入图片描述


锁升级过程

在这里插入图片描述
用markword中最低的三位代表锁状态 其中1位是偏向锁位 两位是普通锁位。

  • 对象的创建时,若偏向锁未启动则创建普通对象,如偏向锁启动则创建匿名对象。偏向锁会在jvm启动后4s默认开启。-XX:+UseBiasedLocking -XX:BiasedLockingStartupDelay=0打开偏向锁时间为0。上偏向锁,指的就是,把markword的线程ID改为自己线程ID的过程。
  • 撤销偏向锁,升级轻量级锁线程在自己的线程栈生成LockRecord ,用CAS操作将markword设置为指向自己这个线程的LR的指针,设置成功者得到锁。
  • 竞争加剧:有线程超过10次自旋, -XX:PreBlockSpin, 或者自旋线程数超过CPU核数的一半, 1.6之后,加入自适应自旋 Adapative Self Spinning , JVM自己控制升级重量级锁:-> 向操作系统申请资源,linux mutex , CPU从3级-0级系统调用,线程挂起,进入等待队列,等待操作系统的调度,然后再映射回用户空间。

锁消除 lock eliminate

public void add(String str1,String str2){
         StringBuffer sb = new StringBuffer();
         sb.append(str1).append(str2);
}

我们都知道 StringBuffer 是线程安全的,因为它的关键方法都是被 synchronized 修饰过的,但我们看上面这段代码,我们会发现,sb 这个引用只会在 add 方法中使用,不可能被其它线程引用(因为是局部变量,栈私有),因此 sb 是不可能共享的资源,JVM 会自动消除 StringBuffer 对象内部的锁。


锁粗化 lock coarsening

public String test(String str){
       
       int i = 0;
       StringBuffer sb = new StringBuffer():
       while(i < 100){
           sb.append(str);
           i++;
       }
       return sb.toString():
}

VM 会检测到这样一连串的操作都对同一个对象加锁(while 循环内 100 次执行 append,没有锁粗化的就要进行 100 次加锁/解锁),此时 JVM 就会将加锁的范围粗化到这一连串的操作的外部(比如 while 虚幻体外),使得这一连串操作只需要加一次锁即可。


锁降级

其实,只被VMThread访问,降级也就没啥意义了。所以可以简单认为锁降级不存在!


深信服PT1-AF实验考试 深信服PT1-AF实验考试实验练习可以去深信服的在线实验平台(链接如下):深信服在线实验平台 (sangfor.com.cn)实验考试其实就是把所有的每一部分实验综合了起来以下内容仅做参考,不确保一样。 阅读详情

相关推荐

乐鑫WIFI芯片开发流程梳理-工具链、编译和下载

最近开始基于乐鑫ESP32的WIFI模组的软件开发,首先要做整套流程的梳理,乐鑫官网以及安信可上已经有了较为系统的资料,但是在实现过程中也遇到了一些问题,花了几天去解决,所以为了总结,也为了给其他人提供一些借鉴,把流程分享一下,官网上相对比较完善的,就不在赘述。 1. 开发方案选择 目前网上有两套较为成熟的方案: (1)基于乐鑫官网推荐的开发方式,原网页:https://docs.espress...

一名嵌入式软件工程师的自我成长 3925

今天会是有offer的一天么:面试时不要再问我CAS和Synchronized的区别了

写在前面 相信很多小伙伴对于CAS,Synchronized相关的问题都很纠结,包括UP也是,对于这几个的区别也困扰了很久。那么今天就来做一个总结。 一. CAS 何为CAS。 CAS(Compare And Swap )是乐观锁的一种实现方式,是一种轻量级锁。JAVA1.5开始引入了CAS,JUC下很多工具类都是基于CAS。 CAS的实现方式 CAS有3个操作数,内存值V,旧的预期值A,要修...

HZGuilty的博客 9482

傻白入门芯片设计,指令集架构、微架构、处理器内核(十一)

通俗理解指令集架构、微架构和处理器内核的关系

qq_46675545的博客 6008

synchronized加锁策略与CAS

线程加锁与CAS

yykkkkll的博客 502

阿里数据集(cluster-trace-v2018)提取

阿里数据集提取 本数据集采用的是阿里集群数据集-2018 详情可参考该文献:https://blog.youkuaiyun.com/weixin_41988248/article/details/92431588 CSV数据集提取操作见:https://blog.youkuaiyun.com/lucky_shi/article/details/105321149 关于read_csv包的用法见:https://blog.youkuaiyun.com/dc19971118/article/details/107721340 从阿里数据集来看,我

5-StarrySky的博客 3340

TPL5010硬件看门狗电路

在做一些采集频率很低的产品的时候,会考虑电池供电,比如表、电气表等,为了控制功耗,往往会在设备不需要工作的时候让它进入低功耗模式。为了设备的稳定性,避免死机后无法恢复,必须配置看门狗,一般的看门狗芯片,喂狗间隔时间是几秒钟。这样在喂狗和低功耗之间就产生了一个矛盾,频繁的喂狗就需要频繁的醒过来,这样功耗就很难做到很低。这颗看门狗芯片,特别适合上面的应用。2小时的间隔意味着主控芯片每2小时醒过来喂狗一次即可,而在2.5V供电的情况下,功耗仅仅35nA,几乎可以忽略不计。

zxm8513优快云博客 3306

synchronized和CAS算法

轻量级锁升级重量级锁:一般两个线程对于同一个锁的操作都会错开,或者自旋等待一下,另一个线程就会释放锁,自旋超过一定次数或者一个线程在持有锁,一个在自旋又来了第三个线程访问时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以为的线程都阻塞,防止CPU空转。始终只有一个线程在执行同步块,在它没有执行完释放锁之前,没有其他线程去执行同步块,在锁无竞争的情况下使用,一旦有了竞争就升级为轻量级锁,升级为轻量级锁的时候需要撤销偏向锁,撤销偏向锁的时候会导致stop the word操作。适用于读多写少的场景。

提供各种学习资源及帮助 468

思维链:让AI更接近人类思维的技术

本文将探讨一种名为“思维链”的技术,它旨在让AI更接近人类思维。文章首先介绍了问题背景与核心概念,接着讲解了算法原理和数学模型,随后阐述了系统分析与架构设计,最后通过项目实战展示了思维链的实际应用,并提供了最佳实践和小结。思维链是一种旨在模拟人类思维过程的技术,它通过构建一系列相互关联的思维方式,实现对复杂问题的分析和解决。思维链算法是一种基于人类思维过程的人工智能算法,它通过构建一系列思维链,实现对问题的分析和解决。智能问答系统是一种常见的人工智能应用,它能够回答用户提出的各种问题。

AI天才研究院 942

【Java并发编程】锁机制——synchronized及乐观锁CAS

详细介绍了sychronized及乐观锁CAS的原理和使用

love and share 1001

获取抖音中x-secsdk-csrf-token的方法

获取抖音中x-secsdk-csrf-token的方法

sh_moranliunian的博客 2017

ABAP 7.40 FOR 表达式与 REDUCE 构造运算符深度解析:从语法新特性到真实项目实践

ABAP 7.40引入了FOR和REDUCE表达式语法,使代码更简洁和函数式。FOR支持内表迭代和条件迭代,可配合VALUE构造新内表,替代传统LOOP。REDUCE用于归约运算,将多值折叠为单一结果,如求和、拼接等。这些新特性让ABAP更现代化,与SAP新架构协同更好,提升了开发效率和代码可读性。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 315

ConcurrentHashMap并发控制源码阅读:CAS与synchronized的应用场景分析

在ConcurrentHashMap的具体实现中,CAS机制和Synchronized协助进行并发控制

Yunwushenyanying的博客 1394

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

cas锁机制

本文讲解CAS机制,主要是因为最近准备面试题,发现这个问题在面试中出现的频率非常的高,因此把自己学习过程中的一些理解记录下来,希望能对大家也有帮助。 什么是悲观锁、乐观锁?在java语言里,总有一些名词看语义跟本不明白是啥玩意儿,也就总有部分面试官拿着这样的词来忽悠面试者,以此来找优越感,其实理解清楚了,这些词也就唬不住人了。 synchronized是悲观锁,这种线程一旦得到锁,其他需要锁的线程就挂起的情况就是悲观锁。 CAS操作的就是乐观锁,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突

进三步的博客 408

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

ConcurrentHashMap 在 JDK 8 中的优化(分段锁 → CAS + synchronized)

ConcurrentHashMap 是 Java 中线程安全的哈希表实现,其核心目标是在多线程环境下提供高效的并发读写能力。JDK 7 与 JDK 8 的实现差异显著,其中 JDK 8 对锁机制进行了重大优化:​。以下从三个维度展开说明。

qq_44431362的博客 1071

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Java多线程.CAS

Java多线程.CAS ABA 自旋锁 乐观锁 悲观锁 自选CAS

记录 分享 成就 1218

JAVA多线程之CAS

介绍了CAS操作,以及其在Java中的实现类,像原子数组,原子更新器,原子累加器以及源码,还有Unsafe方法的一些操作

ifhuke的博客 1291

CAS(Compare and Swap)

CAS(Compare and Swap) 虽然这篇讲CAS,但是这里简单提以下Synchronized Synchronized关键字会让没有得到锁资源的线程进入BLOCKED状态,而后在争夺到锁资源后恢复为RUNNABLE状态,这个过程中涉及到操作系统用户模式和内核模式的转换,代价比较高。 尽管Java1.6为Synchronized做了优化,增加了从偏向锁到轻量级锁再到重量级锁的过度,...

Stu_zkl的博客 697

CAS的特性,乐观锁

CAS(Compare And Swap) 指比较并转换,CAS算法包含三个参数 CAS(V,EN),V表示要更新的变量,E表示预期的值,N表示新值,有仅在V值等于E值时,才会将V值设置成N值,如果V跟E值不同,则说明有其他线程做了更新,当前线程什么都不做,最后返回CAS当前V的真实值; CAS操作采用了乐观锁的思想 乐观嘛,总是以为自己可以成功完成操作。在多个线程同时使用时使用CAS操作一个变量时,只有一个线程会胜出并成功更新,其余均失败,失败的线程不会被挂起,并且允许再次尝试;CAS即使没有锁,也可以发

分享技术,享受生活 1万+

java并发-Synchronized+CAS方式实现读写锁

Synchronized+CAS方式实现读写锁 文章目录Synchronized+CAS方式实现读写锁思路技术代码测试结果[GitHub主页](https://github.com/yinzhongzheng/study) 思路 读可读 读不能写 写不能读 写不可写 技术 CAS 无锁机制,线程安全的更新读写状态 synchronized 读线程的资源控制,控制写写的情况 代码 /** ...

尹忠政的博客 1523

Java CAS是什么,它的底层原理?

对于CAS部分学习,予以记录!

qq_43357394的博客 2062

CAS介绍

CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换。 CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。 更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。 例子: 在内存地址V当中,存储着值为10的变量。 2.此时线程1想要把变量的值增加1。对线程1来说,旧的预期值A=10...

suncat的博客 571

Synchronized 、Atomic 对比 -- JAVA 进阶

在学习CAS无锁时候,总是难免拿来与Synchronized进行比较。 首先先来说一下无锁算法的基本思想: 要实现无锁(lock-free)的非阻塞算法有多种实现方法,其中 CAS(比较与交换,Compare and swap) 是一种有名的无锁算法。CAS, CPU指令,在大多数处理器架构,包括IA32、Space中采用的都是CAS指令,CAS的语义是“我认为V的值应该为A,如果是,那么将V的

qishun2xiao的博客 1682

CAS机制实现原理分析

CAS机制实现原理分析

Ariel_欢 2611

CAS了解及CAS容易发生的问题

    CAS(Compare and Swap)比较和交换,是java在处理并发问题时,使用最多的一种方式,简单说就是,指定一个对象V,给出他的期望值,及需要修改的值,如果期望值等同于内存中的值,那么就把这个对象修改成我们想要改变的值,否则修改失败。 CAS使用最佳实践     先看下我们下面的场景: public class Case { public volatile in...

summerZBH123的博客 6061

悲观锁Synchronized和乐观锁CAS

CAS与Synchronized CAS和Synchronized都可以保证多线程环境下共享数据的安全性。那么他们两者有什么区别? Synchronized是从悲观的角度出发: 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这 样别人想拿这个数据就会阻塞直到它拿到锁 (共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。因此 Synchronized我们也将其称之为悲观锁。jdk中的ReentrantLock也是一种悲观锁。 CAS是从乐观的

Sandul的博客 420

CAS乐观锁

在MyLock中,使用status表示锁的状态,0表示未锁定,1表示锁定,lock()、unlock()使用CAS方法更新,lock()只有在更新成功后才退出,实现了阻塞的效果,不过一般而言,这种阻塞方式过于消耗CPU,MyLock只是用于演示基本概念,实际开发中应该使用Java并发包中的类,如ReentrantLock。这种情况下CAS机制会一直重试,这样就会比较耗费CPU。原子变量的更新逻辑是乐观的,它假定冲突比较少,但使用CAS更新,也就是进行冲突检测,如果确实冲突了,那也没关系,继续尝试就好了。

BASK2311的博客 2596
上一篇: MySQL索引面试(更新)
下一篇: JVM内存模型体系结构(更新)
香草星冰乐
博客等级 码龄7年 21粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值