简述
Java中每个对象都可以用来实现一个同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock)。

具体表现形式如下:

1、普通同步方法,锁的是当前实例对象

2、静态同步方法,锁的是当前Class对象

3、对于同步代码块,锁的是Synchronized括号中的代码块

线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时自动释放锁,无论是通过正常路径退出,还是通过代码块中抛出异常退出。获得内置锁的唯一途径就是进入由这个锁保护的同步方法或代码块。

从 JVM 规范 中 可以 看到 Synchonized 在 JVM 里 的 实现 原理, JVM 基于 进入 和 退出 Monitor 对象 来 实现 方法 同步 和 代码 块 同步, 但 两者 的 实现 细节 不一样。 代码 块 同步 是 使用 monitorenter 和 monitorexit 指令 实现 的, 而 方法 同步 是 使用 另外 一种 方式 实现 的, 细节 在 JVM 规范 里 并没有 详细 说明。 但是, 方法 的 同步 同样 可以 使用 这 两个 指令 来 实现。

monitorenter 指令 是在 编译 后 插入 到 同步 代码 块 的 开始 位置, 而 monitorexit 是 插入 到 方法 结束 处 和 异常 处, JVM 要 保证 每个 monitorenter 必须 有 对应 的 monitorexit 与之 配对。 任何 对象 都有 一个 monitor 与之 关联, 当 且 一个 monitor 被 持有 后, 它将 处于 锁定 状态。 线程 执行 到 monitorenter 指令时, 将会 尝试 获取 对象 所 对应 的 monitor 的 所有权, 即 尝试 获得 对象 的 锁。

对象的内存布局

在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

synchronized 用的锁 是 存在 对象头 中。
如果 对象是数组类型, 则虚拟机用 3 个字 宽( Word) 存储 对 象头, 如果对象是非数组类型, 则用 2字宽存储 对 象头。 在 32位虚拟 机中, 1 字 宽 等于 4 字节, 即 32bit。

  • HotSpot虚拟机的对象头包括两部分信息:
  1. Mark Word   第一部分用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和64bit。
  2. 类型指针       对象头的另外一部分是类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。并不是所有的虚拟机实现都必须在对象数据上保留类型指针,换句话说,查找对象的元数据信息并不一定要经过对象本身,这点将在2.3.3节讨论。
  • 实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。这部分的存储顺序会受到虚拟机分配策略参数(FieldsAllocationStyle)和字段在Java源码中定义顺序的影响。
  • 对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用

详见 https://www.cnblogs.com/kaleidoscope/p/9699329.html

Java内置锁synchronized的实现原理的更多相关文章

  1. Java内置锁synchronized的实现原理及应用(三)

    简述 Java中每个对象都可以用来实现一个同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock). 具体表现形式如下: 1.普通同步方法,锁的是当前实例对象 ...

  2. 深入理解java内置锁(synchronized)和显式锁(ReentrantLock)

    多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两种同步方式.显式锁是JDK1.5引入的,这两种锁有什么异同呢? ...

  3. Java内置锁synchronized的可重入性

    学习自 https://blog.csdn.net/aigoogle/article/details/29893667 对我很有帮助 感谢作者

  4. 深入理解Java内置锁和显式锁

    synchronized and Reentrantlock 多线程编程中,当代码需要同步时我们会用到锁.Java为我们提供了内置锁(synchronized)和显式锁(ReentrantLock)两 ...

  5. jvm内置锁synchronized不能被中断

    很久没看技术书籍了,今天看了一下<七周七并发模型>前面两章讲的java,写的还是有深度的.看到了一个有demo,说jvm内置锁synchronized是不能被中断的.照着书上写了个demo ...

  6. Java内置锁和简单用法

    一.简单的锁知识 关于内置锁 Java具有通过synchronized关键字实现的内置锁,内置锁获得锁和释放锁是隐式的,进入synchronized修饰的代码就获得锁,走出相应的代码就释放锁. jav ...

  7. Java 并发:内置锁 Synchronized

    摘要: 在多线程编程中,线程安全问题是一个最为关键的问题,其核心概念就在于正确性,即当多个线程訪问某一共享.可变数据时,始终都不会导致数据破坏以及其它不该出现的结果. 而全部的并发模式在解决问题时,採 ...

  8. Java 内置锁 重入问题

    阅读<Java并发编程实战>,遇到了一个问题 代码如下 /** * @auther draymonder */ public class Widget { public synchroni ...

  9. Java内置锁的简单认识

    多线程开发离不开锁机制,现在的Java语言中,提供了2种锁,一种是语言特性提供的内置锁,还有一种是 java.util.concurrent.locks 包中的锁,这篇文章简单整理一下内置锁的知识点. ...

随机推荐

  1. jqgrid 加入右键菜单按钮管理

    除了在表格底部添加自定义按钮外,还可以通过设置右键菜单按钮来添加自定义事件.看下图: 如何实现以上功能? 1)引入ContextMenu插件 2)创建一个函数用于初始化右键菜单(本示例取名为 init ...

  2. jQuery上传文件

    1.引入资源 <script src="/yami/backend/backres/js/jquery.min.js"></script> <scri ...

  3. 2017-2018 Exp8 Web基础 20155214

    目录 Exp8 Web基础 实验内容 建站过程 SQL注入 知识点 Exp8 Web基础 实验内容 实验环境 主机 Kali 靶机 Kali 实验工具 后台语言 'PHP' 服务器 'Apache' ...

  4. EZ 2018 03 23 NOIP2018 模拟赛(五)

    链接:http://211.140.156.254:2333/contest/65 这次Rating重回Rank18,我是20的守门员(滑稽) 这次题目和数据普遍偏水,我T2打错了一个变量名竟然过了所 ...

  5. Ansible入门笔记(1)之工作架构和使用原理

    目录 Ansible入门笔记(1) 1.Ansible特性 2.ansible架构解析 3.ansible主要组成部分 1)命令执行来源: 2)利用ansible实现管理的方式 3)Ansile-pl ...

  6. ubuntu 桌面操作系统安装WPS办公软件的方法

    1.打开ubuntu系统自带的firefox软件 2.打开linux.wps.cn,并点击立即下载 3. 点击下载deb安装包 4.进入下载目录,sudo dpkg -i wps-office_10. ...

  7. [BZOJ4851][JSOI2016]位运算[矩阵快速幂]

    题意 给定长度为 \(\rm |S|\) 的 \(\rm 01\) 串并将其倍长 \(k\) 次得到一个 \(\rm|S|\times k\) 位的二进制数 \(R\) ,求有多少种在 \([0,R- ...

  8. JavaScript快速入门-ECMAScript本地对象(Array)

    Array对象 Array对象和python里面的list对象一样,是用来存储多个对象值的对象,且方法和属性基本上类似. 一.属性 lenght 二.方法  1.concat()  用于连接两个或多个 ...

  9. 设计模式 笔记 单例模式 Singleton

    //---------------------------15/04/09---------------------------- //Singleton 单例模式-----对象创建型模式 /* 1: ...

  10. Boyer and Moore Fast majority vote algorithm(快速选举算法)

    问题来来自于leetcode上的一道题目,https://leetcode.com/problems/majority-element/,大意是是找出一个数组中,出现次数超过一个半的数字,要求是O(n ...