09. 小伙子, 听说你对synchronized理解很深?...

激光雷达与相机融合(四)----基于激光雷达与相机的碰撞检测 在这一部分,基于前面的各个部分内容,将利用激光雷达和相机实现目标的检测分类及单目标跟踪,并对车辆前方的车辆目标计算相应的碰撞时间TTC。计算方法分别利用相机和雷达实现。 1.系统的总体架构: 2.TTC计算 简单介绍一下通过激光雷达和相机计算碰撞时间的原理: 利用激光雷达点计算碰撞时间:首先根据检测框聚类出前车目标的点,并过滤掉这些点中的离群点,然后找出这些点中相对于本车最近的点,基于前后两帧以及数据采集频率就可以求解出相对速度,然后用当前帧的距离除以速度得出当前的TTC。但该方法对最近点的选取稳定性不是 阅读详情

大佬: 你这段代码有线程安全问题, 解决下!
我:      ……   image

大佬:      Synchronized加上,  别锁方法, 锁必要的代码块就好, 这样性能高点.

我:        哦, 好的…………(ps, 迅速百度……)image

前言

Synchronized(也叫同步)是 Java 中解决并发问题的一种最常用的方法.

在 JDK1.5 之前, synchronized 是一个**重量级锁, 相对于j.u.c.Lock**,显得很笨重.

随着 Javs SE 1.6 对 synchronized 进行的各种优化, synchronized 再次焕发了生机.

下面, 我们一起探索 synchronized 的基本使用及原理

基本使用

前面我们讲过, synchronized 可以保证线程安全.

它的作用主要有三个

  • 原子性

确保线程“互斥”的访问同步代码

  • 可见性

保证**共享变量的修改能够及时可见,
主要通过Java内存模型中的以下特征来保证
“
对一个变量
unlock操作之前,必须要同步到主内存中;
如果对一个变量进行
lock操作,则将会清空工作内存中此变量的值,
在执行引擎使用此变量前,需要重新从主内存中
load操作或assign**操作初始化变量值
”

  • 有序性

解决**重排序问题,
即“一个
unlock操作先行发生(happen-before)于后面对同一个锁的lock**操作”

从语法上讲,synchronized 可以把任何一个**非 null 对象作为"锁"**,

在 HotSpot JVM (使用最广泛的java虚拟机)实现中,

锁有个专门的名字: 对象监视器(Object Monitor).

synchronized有三种方式来加锁, 分别是:

  • 方法锁 synchronized void method()

  • 对象锁 synchronized(this)

  • 类锁 synchronized(Demo.Class)

其中在**方法锁** 层面可以有如下3种方式:

  • 修饰**非静态方法时,监视器锁便是对象实例(this)**;

  • 修饰**静态方法时,监视器锁便是对象的 Class 实例**,因为 Class 数据存在于永久代,因此静态方法锁相当于该类的一个全局锁;

  • 修饰某一个**对象实例时, 监视器锁便是括号括起来的对象实例**;

注意:

synchronized内置锁是一种对象锁(锁的是对象而非引用变量),作用粒度是对象 ,可以用来实现对临界资源的同步互斥访问,是可重入的, 其可重入最大的作用是避免死锁.

如子类同步方法调用了父类同步方法,如没有可重入的特性,则会发生死锁;

synchronized同步原理

数据同步需要依赖锁,那锁的同步又依赖谁?

synchronized 是在软件层面依赖 JVM(基于JVM的内置锁Monitor实现);而 j.u.c.Lock 是在硬件层面依赖特殊的 CPU 指令.

我们都知道, synchronized的使用遵循以下规则:

当一个线程访问同步代码块时,首先是需要得到锁才能执行同步代码,当退出或者抛出异常时必须要释放锁,

那么它是如何来实现这个机制的呢?

对象锁: synchronized (this)

我们先看一段简单的代码:

public class Test {
    public void method() {
        synchronized (this) {
            System.out.println("Hello World!");
        }
    }
}

编译

javac Test.java

反汇编

javap -v Test.class

image.png

下面, 我们针对代码的重要指令进行说明

monitorenter

每个对象都是一个监视器锁(monitor).
当 monitor 被占用时就会处于锁定状态,
线程执行 monitorenter 指令时会尝试获取 monitor 的所有权

过程如下:

  • 如果 monitor 的进入数为 0,则该线程进入 monitor,然后将进入数设置为 1,该线程即为 monitor 的所有者;
  • 如果线程已经占有该 monitor,只是重新进入,则进入 monitor 的进入数加 1;
  • 如果其他线程已经占用了 monitor,则该线程进入阻塞状态,直到 monitor 的进入数为 0,再重新尝试获取 monitor 的所有权;

monitorexit

执行 monitorexit 的线程必须是 objectref 所对应的 monitor 的所有者.
指令执行时,monitor 的进入数减 1,
如果减 1 后进入数为 0,那线程退出 monitor,
不再是这个 monitor 的所有者.
其他被这个 monitor 阻塞的线程可以尝试去获取这个 monitor 的所有权.

细心的朋友会在截图中发现

不对啊, 指令中出现了两次monitorexit?

其实是这样的:

正常情况下, 同步代码块会调用第一个monitorexit释放锁;
如果同步代码块中出现异常,则调用第二个monitorexit来保证释放锁;

通过上面两段描述,我们应该能很清楚的看出 synchronized 的实现原理,

synchronized 的语义底层是通过一个 monitor 的对象来完成.
其实 wait/notify 等方法也依赖于 monitor 对象,
这就是为什么只有在同步的块或者方法中才能调用 wait/notify 等方法,
否则会抛出**java.lang.IllegalMonitorStateException**的异常的原因.

方法锁 synchronized void method()

再来看一下同步方法

public class Test {
    public synchronized void method() {
        System.out.println("Hello World!");
    }
}

反汇编

image.png

从编译的结果来看,

方法的同步 并没有通过指令 monitorenter 和 monitorexit 来完成(理论上也可以通过这两条指令来实现),
不过相对于普通方法, 其常量池中多了 **ACC_SYNCHRONIZED**标示符.

JVM 就是根据该标示符来实现方法的同步的:

当方法调用时,调用指令将会检查方法的 ACC_SYNCHRONIZED 访问标志是否被设置,
如果设置了,执行线程将先获取 monitor,
获取成功之后才能执行方法体,
方法执行完后再释放 monitor.
在方法执行期间,其他任何线程都无法再获得同一个 monitor 对象.

synchronized(this) 和 synchronized void method() 两种同步方式本质上没有区别,

只是方法的同步是一种隐式的方式来实现,无需通过字节码来完成.

而monitorenter 和 monitorexit两个指令的执行是 JVM 通过调用操作系统的互斥原语 mutex 来实现的, 被阻塞的线程会被挂起,等待重新调度, 这样会导致“用户态和内核态”来回切换, 对性能有较大影响.

请关注我的订阅号

订阅号.png

android mtk camera如何自定义默认拍照与录像分辨率 本文详细解析了在Android MTK平台上自定义相机默认拍照与录像分辨率的方法。通过分析Camera2应用默认选择逻辑,定位并修改PictureSize.java与VideoQualityCaptureRequestConfig.java中的关键代码,实现绕过系统智能选择,强制指定最高或特定分辨率。文章还提供了进阶的可配置化方案与验证避坑指南,帮助开发者精准控制相机行为。 阅读详情

相关推荐

游戏开发实战:用UE4 Marschner模型打造次世代头发渲染(附Shader代码解析)

本文详细解析了如何在UE4中使用Marschner模型实现次世代头发渲染,包括Shader代码逐行解读与参数调优。通过对比传统Kajiya-Kay模型,展示了Marschner模型在物理精确性和视觉效果上的优势,并提供了性能优化与实战技巧,帮助技术美术师提升游戏角色渲染品质。

weixin_28223453的博客 239

【五】Java多线程之线程同步synchronized(同步方法、同步代码块、偏向锁、轻量级锁、自旋锁、重量级锁、消除锁)

线程同步需要关键字synchronized来锁资源。 有两种线程同步的方式 1.同步化方法 使用synchronized关键字修改方法来同步化对方法的访问。 当调用方法时,调用线程进入对象监视器,对象监视器锁住对象(锁住synchronized修饰的那个方法的类的当前对象)。 在对象被锁住的同时,其他线程不能进入该方法,也不能进入该对象定义的其他同步化方法,但是该对象的非同步化方法可以被...

Sid小杰的博客 509

树莓派5安装ROS1避坑指南:从系统配置到cmake报错全解决

本文详细介绍了在树莓派5上安装ROS1的完整流程,包括系统配置、环境变量设置、cmake报错解决等关键步骤。针对树莓派5的ARM架构特性,提供了从基础安装到高级调试的系统级解决方案,帮助开发者高效部署ROS1并避免常见编译陷阱。特别针对cmake报错问题,给出了深度解析和实用修复方法。

spark7igniter的博客 233

深入分析Synchronized原理(阿里面试题)

还有一篇 讲解lock的实现原理,参考:解决多线程安全问题-无非两个方法synchronized和lock 具体原理以及如何 获取锁AQS算法 (百度-美团) 还有一篇写的不错:深入理解synchronized底层原理,一篇文章就够了! 另一篇少的:synchronize原理 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synch...

489

陆地观测卫星数据服务平台深度体验:高分、中巴、资源系列影像的检索与下载技巧

本文深度解析国产陆地观测卫星数据服务平台的使用技巧,重点介绍高分、中巴、资源系列卫星影像的检索与下载方法。通过权限体系解析、高级检索策略、数据预处理等实战技巧,帮助用户高效获取高质量遥感数据,适用于环境监测、资源调查等多种应用场景。

eee77的博客 980

电磁波成像技术全解析:从γ射线到无线电波的应用实践

本文全面解析电磁波成像技术,从γ射线到无线电波的应用实践。详细介绍了不同波长电磁波的特性与实用场景,包括医疗影像、工业检测、安防监控等领域。特别探讨了X射线、红外热成像、毫米波雷达等前沿技术的实战应用,为读者提供技术选型指南和操作技巧。

weixin_29305337的博客 292

转载一篇详尽的Synchronized底层理解

记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线程情况的百试不爽的良药。但是,随着学习的进行我们知道在JDK1.5之前synchronized是一个重量级锁,相对于j.u.c.Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它。 不过,随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得

白白胖胖充满希望 434

从jieba分词到BERT-wwm——中文自然语言处理(NLP)基础分享系列(12)

今天是本系列的最后一期,完整代码呈现Huggingface transformers平台上微调BERT-wwm-ext的过程方法。

weixin_49518391的博客 3762

Java 并发编程实战重入锁(子类同步方法调用父类的同步方法)

看如下代码public class Widget { public synchronized void doSomething () { System.out.println(this.toString()+"---------------------"); } }public class LoggingWidget extends Widg...

weixin_34092455的博客 705

从实验室到生产线:Qwen3-Omni后训练技术在实际业务中的落地挑战

本文探讨了Qwen3-Omni后训练技术在实际业务中的落地挑战,重点分析了多模态AI在工业应用中的关键问题与解决方案。通过金融风控、跨境电商等场景案例,揭示了通用模型与垂直需求的矛盾,并提供了知识蒸馏、语音合成优化等实战经验,助力企业实现技术到业务的转化。

weixin_29035147的博客 265

Python无法拒绝的表白界面(完整代码)

Python制作一个无法拒绝的表白界面的完整代码。

AIGC 5万+

JVM 多线程高并发--synchroized

1.synchroized 基本用法 1.1语义 原子性:确保线程互斥的访问同步代码 可见性:保证共享变量的修改能够即时可见,其实通过对Java内存模型中“对一个变量unlock操作之前,必须同步到主内存中;如果对一个变量进行lock操作,则将会清空工作内存中此变量的值,在执行引擎使用此变量前,需要重新从主内存中load操作或者assign操作初始化变量值”来保证。 有序性:有效的解决重排问题,即“一个unlock操作先行发生(happen-before)于后面对同一个锁的loc

月芽之上的专栏 1052

SPD-Conv+YOLOv8:空间深度转换卷积赋能小目标检测,从原理到实战的科研级优化指南

从理解SPD-Conv“空间到深度+逐步卷积”的核心设计,到亲手将其嵌入YOLOv8并验证在小目标场景的表现,再到基于此探索属于自己的科研与工程方向——这个过程能让你深刻理解“小目标特征保留”在检测任务中的核心价值。现在就开始行动,相信你会在小目标检测的“细节捕捉”之路上,走出一条属于自己的技术路径。实验通常会证明:嵌入SPD-Conv后,YOLOv8在小目标AP上提升5-8个百分点,mAP50-95提升3-5个百分点,而推理速度仅下降5%以内,充分体现了其“保细节+提精度”的优势。

m0_64661770的博客 161

一篇看懂synchronized原理

2222

qq_35599414的博客 636

廖雪峰Python教程[完整版]

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

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

13. 大佬问我: notify()会立刻释放锁么?

大佬问我: notify()会立刻释放锁么? ​ 我的内心戏: 肯定会啊! 这么简单的问题? 聪明如我, 决定装小白, 回答: 不会? 大佬: 很好, 小伙子基础不错! 我: 大佬: 说说为什么 我: ……………… 于是, 有了这篇文章! 问题的根本原来在于 “立刻”这个描述词! 如果你和咸鱼君一样懵逼, 不妨往下看! 技术大佬可以告辞了!! 接下来, 我们深入的分析分析wait和notify 前言 前面介绍了Synchronized关键词的原理与优

CTO技术的博客 1504

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

08. 今天, 小姐姐突然问了我一个问题……

前言 今天, 妹子突然找我, 问了我一个问题…… 她要买笔记本电脑 (突然的失望……) 她不是小白, 知道电脑要看内存, CPU,显卡以及固态硬盘等等 甚至知道 N卡 和 A卡的区别 但是依旧被CPU的 “i5处理器 双核四线程” “i5处理器 双核双线程” …… 这些描述给整懵了… 妹子知道我是“码农”, 所以直接问我了 “ CPU的双核双线程和双核4线程有啥什么区别? ” 虽然我不明白“码农”为什么要知道这些…… ** 不过, 巧了, 咸鱼君刚好知道!(差点不知道, 多影响形象!) 那么, 在CPU

CTO技术的博客 607

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

06. 就该这么学并发 - 如何保证线程安全

前言 上节,我们对线程安全有了较全面的认知. 我们知道, 线程之所以不安全, 主要是多线程下对可变的共享资源的争用导致的. 衡量线程是否安全, 主要从三个特性入手 原子性 可见效 有序性 只要保证了这三个特性,我们就认为线程是安全的, 多线程下执行结果才会和单线程执行结果统一起来. 本章,我们就来聊聊**如何保证线程安全**的问题. 如何保证原子性 常用的保证Java操作原子性的工具是**锁和同步方法(或者同步代码块)**. 我们举个例子: public class Test { privat

CTO技术的博客 510

03. 就该这么学并发 - 线程的阻塞

前言 上章介绍了**线程生命周期的就绪和运行**状态 这章讲下线程生命周期中最复杂的**阻塞**状态 阻塞(Blocked) 在开始之前 我们先**科普**几个概念 阻塞,挂起,睡眠 区分 阻塞 在线程执行时,所需要的资源不能立马得到,则线程被“阻塞”,直到满足条件则会继续执行 阻塞是一种“被动”的状态 挂起 线程执行时,因为“主观”需要,需要暂停执行当前的线程,此时需要“挂起”当前线程. 挂起是“主动”的动作行为,因为是“主动”的,所以“挂起”的线程需要“唤醒”才能继续执行 睡眠 线程执行时,因为“主

CTO技术的博客 389

07. 就该这么学并发 - 上下文切换

前言 前面的几章, 我们有提到个名词“上下文切换” 这是个什么东西呢? 其实很好理解, 我们看一本书籍时,往往间隔的看(很少有人一天看完的吧?!), 那么如何保证自己下次是从上一次断点处看呢? 显而易见, 我们用书签! “上下文切换”就是计算机的“书签”. 本章,我们来学习“上下文切换”原理以及如何减少“上下文切换”. 在此之前, 还得先复习下前面提到的进程和线程, 因为上下文切换的对象就是进程和线程. 线程与进程 进程是操作系统的管理单位,也是系统分配资源的基本单位; 线程则是进程的管理单位, 也是是CP

CTO技术的博客 362

01. 就该这么学并发 - 线程的创建(多姿势)

本章开始,咸鱼君将开启一个新的专栏 就该这么学并发 来记录学习Java并发编程的相关内容~ 前言 说到**并发编程,就不得不先说多线程,因为并发的本质就是多线程的处理** 进程和线程 进程 (ps: 每一个程序就是一个进程) 进程指运行中的应用程序,每个程序运行时就会开启一个进程 进程是系统分配资源的最小单位 进程有独立系统资源(进程间的资源是隔离的) 每个进程至少有一个线程 - 线程 (ps: 进程至少有一个线程) 线程依托于进程 线程除了支持本身运行的一点系统资源外(如: 控制线程运

CTO技术的博客 343

12. 面试官不问, 你也不得不知道的锁知识!

前言 hello, 大家好, 我是咸鱼君, 擅长各种Java摸鱼姿势. 恰逢2020年“金九”月, 今天, 我们就来说一说面试中出现频率极高的锁知识! ps:说不定可以帮到部分有“想法”的同学 锁的优化 JDK6开始, synchronized的实现机制进行了较大调整,除了使用JDK5引进的CAS自旋之外, 还增加了以下的优化策略. 自适应的CAS自旋 锁消除 锁粗化 偏向锁 轻量级锁 … 这些优化使得synchronized性能获得了极大提高, 所以, 情况允许下, 推荐使用synchronize

CTO技术的博客 325

11. 嗨, 需要谈个对象…………?

嗨, 空闲时间, 谈个对象…………头? 对不起, 咸鱼君又调皮了. 今天, 我要和你谈的不是对象, 而是对象头. 没错, 就是Java对象里的对象头知识. (专业技术文, 阅读需谨慎) 前言 上章我们说了synchronized的基本原理, 了解到了synchronized的三种加锁方式 方法锁 类锁 对象锁 抱着往底层深挖的心态, 本章继续深入了解synchronized, 看看在底层, synchronized锁究竟是怎么实现的! 为了说清synchronized锁的底层原理,我们得先

CTO技术的博客 287

04. 就该这么学并发 - 线程的结束

前言 接上章“线程的阻塞”,我们继续讲线程的生命周期中最后一个状态“销毁” 销毁(Dead) 线程会以如下3种方式结束,结束后就处于死亡状态: - run()或call()方法执行完成,线程正常结束 - 线程抛出一个未捕获的Exception或Error - 直接调用该线程stop()(已废弃,不推荐使用)方法来结束该线程, 该方法容易导致死锁,通常不推荐使用 线程一旦死亡,就不能复生. 如果在一个死去的线程上调用**start()**方法,会抛出 java.lang.IllegalThreadS

CTO技术的博客 276

02. 就该这么学并发 - 线程的就绪与执行

前言 接上章“线程的创建”, 本章我们聊聊线程生命周期的“就绪”和“运行”状态. 就绪(Runnable) 线程对象的start()方法被调用后,该线程即进入就绪状态 - 此时JVM会为其创建方法调用栈和程序计数器; - 该状态的线程一直处于"线程就绪队列" 尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列, 因为CPU的调度不一定是按照先进先出的顺序来调度的 - 此时线程等待系统为其分配CPU时间片,并不是说执行了start()方法就立即执行 简而言之, 假设有子线程t, 那么

CTO技术的博客 258

10. 谁再和我提内核/用户态, 我跟谁…………

前言 谁再和我提内核/用户态, 我跟谁…… 记不清哪天了, 咸鱼刚入职场, 依稀记得某天的下午时光, 公司内的一群大牛, 聚在一起     尽讨论一些高大上的技术话题, 或底层原理, 或架构…… 时不时传来一些专业术语“用户态”,“内核态”………… 咸鱼在边上默默听着, 也不敢插嘴,    只能仰望大佬, 同时暗下决心,  今天一定要把这两个概念搞懂! 那么, 用户态和内核态代表究竟是个啥? 用户态和内核态 简而言之

CTO技术的博客 246

05. 就该这么学并发 - 线程安全

前言 通过前几章对“线程生命周期”的讲解, 相信大家对于线程有了基本的了解. 本章,我们就来聊聊**线程安全**问题. 线程安全 一般我们说到线程安全, 都是**针对多线程的(单线程不存在线程安全问题**) 多线程之所以会出现安全问题, 主要是因为 存在同时访问同一个共享、可变资源的情况 这种资源可以是:一个变量、一个对象、一个文件等 共享 意味着该资源可以由多个线程同时访问 可变 意味着该资源可以在其生命周期内被修改 简而言之,如果 代码在多线程下执行和在单线程下执行永远都能获得一样的结果

CTO技术的博客 230
上一篇: 08. 今天, 小姐姐突然问了我一个问题……
下一篇: 别说我没提醒你……
码哥说
博客等级 码龄8年 5645粉丝 172原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

码哥说

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

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

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

打赏作者

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

抵扣说明:

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

余额充值