展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Java中的Synchronized关键字原理及应用

Java中的Synchronized关键字原理及应用

源码级别剖析Synchronized对象结构Synchronized是Java中的隐式锁,它的获取锁和释放锁都是隐式的,完全交由JVM帮助我们操作,在了解Synchronized关键字之前,首先要学习的知识点就是Java的对象结构,因为Synchronized锁就是存放在Java对象中的,Java对象结构如下图所示:可以清晰的看到Java对象由三部分组成,分别是对象头、实例数据、填充数据,我们的锁就存放在对象头中,接下来我们将对对象结构做一个简单的解析:mark-down:对象标记字段占8个字节,用于存储

本文目录

      源码级别剖析Synchronized

      对象结构

      Synchronized是Java中的隐式锁,它的获取锁和释放锁都是隐式的,完全交由JVM帮助我们操作,在了解Synchronized关键字之前,首先要学习的知识点就是Java的对象结构,因为Synchronized锁就是存放在Java对象中的,Java对象结构如下图所示:

      Java中的Synchronized关键字原理及应用

      可以清晰的看到Java对象由三部分组成,分别是对象头、实例数据、填充数据,我们的锁就存放在对象头中,接下来我们将对对象结构做一个简单的解析:

      • mark-down:对象标记字段占8个字节,用于存储有关锁的标记位等信息,从图中可以看出有哈希值、轻量级锁的标记位、偏向锁标记位等。

      • Klass Pointer:Class对象的类型指针,它就是指向当前对象属于哪个Class类的指针,jdk1.8默认开启压缩指针后占用4个字节,关闭压缩指针后占用8个字节。

      • 对象实际数据:这部分内容包括对象的所有成员变量,大小由各个成员变量决定,比如byte占用1个字节、int占用4个字节等。

      • 对其填充:这部分内容仅仅只是做到空间补全,就是一个占位符的作用,因为HotSpot虚拟机的内存管理系统要求对象的起始地址必须是8字节的整数倍,因此如果出现对象实例没有对齐的话,就需要通过对其填充来补充。

      在mark-down锁类型标记中,可以看到总共有五种类型,分别是无锁、偏向锁、轻量级锁、重量级锁、GC标记,所以如果只是使用2比特标记是无法完全被表示出来的,所以引入了一位偏向锁标记,也就是说001为无锁、101为偏向锁。

      Monitor 对象

      上面介绍了对象结构,可以看到在Mark-down中会存储不同的锁信息,当锁的状态为重量级锁(10)时,Mark-down中会存放一个指向Monitor对象的指针,这个Monitor对象也称为监视器锁。

      synchronized的运行机制,就是JVM检测到共享对象存在不同的竞争情况的时候,会自动切换到适合的锁实现,这种切换就是锁的升级、降级。(很多地方都说锁只能升级,不能降级,其实这种说法是错误的,在《Java并发编程的艺术》书中说到,对于偏向锁来说,它可以进行降级到无锁状态,也叫做偏向锁的撤销)。

      那么现在就存在着三种不同的Monitor实现,分别是偏向锁、轻量级锁和重量级锁。如果一个Monitor被一个线程持有的时候,就说明这个线程拿到了锁。

      Java中的Monitor是基于C++的ObjectMonitor实现的,它的主要成员包括:

      • _owner:指向持有ObjectMonitor对象的线程

      • _WaitSet:存放处于wait状态的线程队列,即调用wait()方法的线程

      • _EntryList:存放处于等待锁Block状态的线程队列

      • _count:约为_WaitSet+_EntryList的节点数之和

      • _cxq:多个线程争抢锁,会先存入这个单向链表

      • _recursions:记录重入次数

      • _object:存储的Monitor对象

      获取Monitor对象的线程进入_owner区的时候,_count+1,如果线程调用了wait()方法,那么会释放Monitor对象(释放锁),_owner恢复为空同时_count-1。此时该线程进入_WaitSet队列中,等待被唤醒。

      从上述的描述可以看出,synchronized关键字获取锁的关键在于每个对象的对象头中,这也就能解释了为什么synchronized()括号里存放任何对象都能获得锁的特征。

      Synchronized特征

      原子性

      原子性,就是说一个操作要么完成,要么不完成,不存在完成一半的情况,也就是说这个操作是不可中断的。

      synchronized可以保证同一时间内只有一个线程拿到锁,进入到代码块去执行代码,这样说如果不能理解,那么就想象下面的一个场景,有一个厕所只有一个坑位,并且厕所还上锁了,就是为了防止多人一起上厕所的不文明现象,每个人上厕所都必须要去厕所管理员处缴费,缴费后才能拿到锁再去上厕所,上完厕所再把要是还给厕所管理员,synchronized就是厕所管理员,保证一次只能有一个人拿到锁,并且每个人用完厕所之后都必须要归还钥匙。

      接下来看到下面一个同步加方法:

      public static void add() {
          synchronized (Demo.class) {
              counter++;
          }
      }

      将其进行反编译后查看代码:

      javap -v -p Demo

      public static void add();
          descriptor: ()V
          flags: ACC_PUBLIC, ACC_STATIC , ACC_SYNCHRONIZED
          Code:
            stack=2, locals=2, args_size=0
               0: ldc           #12                 // class
               2: dup
               3: astore_0
               4: monitorenter
               5: getstatic     #10                 // Field counter:I
               8: iconst_1
               9: iadd
              10: putstatic     #10                 // Field counter:I
              13: aload_0
              14: monitorexit
              15: goto          23
              18: astore_1
              19: aload_0
              20: monitorexit
              21: aload_1
              22: athrow
              23: return
            Exception table:

      可以看到有两个指令明显和monitor有关:

      • monitorenter:在判断拥有同步标识 ACC_SYNCHRONIZED 抢先进入此方法的线程会优先拥有 Monitor 的 owner ,此时计数器 +1

      • monitorexit:当执行完退出后,计数器 -1,归 0 后被其他进入的线程获得

      可见性

      可见性指的是当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他的线程能够立马感知,能看到修改后的值。(线程的可见性和一个叫JMM的东西息息相关,后面会写一篇关于可见性结合volatile关键字的文章)

      而Synchronized拥有可见性,因为它加锁和释放锁都有如下语义:

      • 线程加锁前,必须清空工作内存中共享变量的值,从而从主内存中读取最新的共享变量的值。

      • 线程释放锁时,必须把共享变量的值刷新到主内存中。

      • synchronized的可见性依赖于操作系统内核互斥锁实现,相当于JVM中的lock,unlock,退出代码块时需要刷新共享变量到主内存中,这一点和volatile关键字不一样,volatile关键字的可见性是依赖于内存屏障(也叫内存栅栏)来实现的。

      有序性

      as-if-serial,就是保证不管编译器和处理器为了性能优化怎样进行指令重排序,都需要保证单线程下的运行结果的正确性。也就是常说的:如果在本线程内观察,所有的操作都是有序的,如果在一个线程观察另一个线程,所有的操作都是无序的。

      注意,这里的有序性和volatile是不一样的,它并不是volatile的防止指令重排序。

      可重入锁

      可重入锁的概念很简单,就是一个线程可以多次获取自己持有的对象锁,这种锁就是可重入锁,同样的释放锁也就需要释放相同数量的锁。synchronized锁对象中就有一个计数器,用于存放获取锁的次数,也就是重入次数。

      锁升级的过程

      synchronized 锁有四种交替升级的状态:无锁、偏向锁、轻量级锁和重量级,这几个状态随着竞争情况逐渐升级,后续会补上一张完整的锁升级图。

      本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
      作者最新文章
      编程开发 Java
      相关文章 更多
      精品专题 更多
      装机必备

      正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

      Windows

      正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

      PDF教程

      正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

      macOS软件

      正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

      IOS软件

      正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

      AI

      正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

      Mac软件 更多
      Aperty macOS版
      Aperty macOS版

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      火山引擎 网页版
      火山引擎 网页版

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      立刻MV 网页版
      立刻MV 网页版

      立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

      蛙蛙写作 网页版
      蛙蛙写作 网页版

      蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

      讯飞智作 网页版
      讯飞智作 网页版

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      超级简历WonderCV 网页版
      超级简历WonderCV 网页版

      超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

      音述AI 网页版
      音述AI 网页版

      音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

      AionClaw macOS版
      AionClaw macOS版

      AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

      Loomy macOS版
      Loomy macOS版

      Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

      AirBuddy 3 macOS版
      AirBuddy 3 macOS版

      AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

      AirServer macOS版
      AirServer macOS版

      AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

      AnyDesk macOS版
      AnyDesk macOS版

      AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

      WINDOWS 更多
      讯飞绘文 网页版
      讯飞绘文 网页版

      讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

      Maya(Autodesk Maya) Windows版
      Maya(Autodesk Maya) Windows版

      Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

      Aperty Windows版
      Aperty Windows版

      Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

      火山引擎 网页版
      火山引擎 网页版

      火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

      立刻MV 网页版
      立刻MV 网页版

      立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

      蛙蛙写作 网页版
      蛙蛙写作 网页版

      蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

      讯飞智作 网页版
      讯飞智作 网页版

      讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

      超级简历WonderCV 网页版
      超级简历WonderCV 网页版

      超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

      音述AI 网页版
      音述AI 网页版

      音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

      AionClaw Windows版
      AionClaw Windows版

      AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

      Loomy Windows版
      Loomy Windows版

      Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

      AirServer Windows版
      AirServer Windows版

      AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。