1.Monitor对象

Monitor对象被称为管程或者监视器锁

在Java中,每一个对象实例都会关联一个Monitor对象。

这个Monitor对象既可以与对象一起创建销毁,也可以在线程试图获取对象锁时自动生成。

当这个Monitor对象被线程持有后,它便处于锁定状态。Synchronized的基本原理就是能否获取Monitor的所有权。

monitor
ObjectMonitor() {
_header = NULL;
_count = 0; //用于记录线程获取锁的次数,成功获取到锁后count会加1,释放锁时count减1
_waiters = 0,
_recursions = 0;// 线程重入次数
_object = NULL; // 存储Monitor对象
_owner = NULL; // 持有当前线程的owner
_WaitSet = NULL;// wait状态的线程列表
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ; // 单向列表
FreeNext = NULL ;
_EntryList = NULL ;// 处于等待锁状态block状态的线程列表
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
_previous_owner_tid = 0;
}

2.对象头

在对象头的MarkWord中主要存储了对象自身的运行时数据,例如哈希码、GC分代年龄、锁状态、线程持有的锁、偏向线程ID等



当对象为偏向锁时,Mark Word存储了偏向线程的ID;

当状态为轻量级锁时,Mark Word存储了指向线程栈中Lock Record的指针;

当状态为重量级锁时,Mark Word存储了指向堆中的Monitor对象的指针。

3.锁升级

偏向锁

偏向锁的核心思想是,如果一个线程获得了锁,那么锁就进入偏向模式,此时Mark Word的结构也变为偏向锁结构,即将对象头中Mark Word的标记位改为1,并且在Mark Word中记录该线程的ID。

轻量级锁

Mark Word中的部分字节CAS更新指向线程栈中的LockRecord,如果更新成功,则轻量级锁获取成功_,记录锁状态为轻量级锁;否则,说明已经有线程获得了轻量级锁,目前发生了锁竞争(不适合继续使用轻量级锁),接下来膨胀为重量级锁。

JVM会在当前线程的线程栈中开辟一块单独的空间,里面保存指向对象锁MarkWord的指针,同时在对象锁Mark Word中保存指向这片空间的指针。上述两个保存操作都是CAS操作,如果保存成功,代表线程抢到了同步锁,就把MarkWord中的锁标志位改成00,可以执行同步代码。如果保存失败,表示抢锁失败

自旋锁

空循环一般不会执行太多次,可能是50个循环或100循环,在经过若干次循环后,如果得到锁,就顺利进入同步代码。如果还不能获得锁,那就会将线程在操作系统层面挂起,即进入到重量级锁。

重量级锁

重量级锁通过对象内部的monitor实现(见上文的MonitorObject模式)

monitor的本质是依赖于底层操作系统的MutexLock实现,操作系统实现线程间的切换是通过用户态与内核态的切换完成的,而切换成本很高

MutexLock最核心的理念就是尝试获取锁.若可得到就占有.若不能,就进入睡眠等待

4.其他概念

锁消除

JVM在编译时通过对运行上下文的描述,去除不可能存在共享资源竞争的锁,通过这种方式消除无用锁,即删除不必要的加锁操作,从而节省开销

锁膨胀

将多次连接在一起的加锁、解锁操作合并为一次,将多个连续的锁扩展成一个范围更大的锁

如果虚拟机检测到有一系列连串的对同一个对象加锁和解锁操作,就会将其合并成一次范围更大的加锁和解锁操作,即在第一次append方法时进行加锁,最后一次append方法结束后进行解锁

[Thread] Synchronized的更多相关文章

  1. java基础温习 -- Thread synchronized关键字

    synchronized 基本规则 1. 当一个线程访问“某对象”的“synchronized方法”或者“synchronized代码块”时,其他线程对“该对象”的该“synchronized方法”或 ...

  2. 让面试官心服口服:Thread.sleep、synchronized、LockSupport.park的线程阻塞有何区别?

    前言 在日常编码的过程中,我们经常会使用Thread.sleep.LockSupport.park()主动阻塞线程,或者使用synchronized和Object.wait来阻塞线程保证并发安全.此时 ...

  3. Java并发编程:synchronized

    Java并发编程:synchronized 虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就 ...

  4. JAVA笔记 之 Thread线程

    线程是一个程序的多个执行路径,执行调度的单位,依托于进程存在. 线程不仅可以共享进程的内存,而且还拥有一个属于自己的内存空间,这段内存空间也叫做线程栈,是在建立线程时由系统分配的,主要用来保存线程内部 ...

  5. 【转】Java并发编程:synchronized

    一.什么时候会出现线程安全问题? 在单线程中不会出现线程安全问题,而在多线程编程中,有可能会出现同时访问同一个资源的情况,这种资源可以是各种类型的资源:一个变量.一个对象.一个文件.一个数据库表等,而 ...

  6. 高并发编程基础Synchronized与Volatile

    关键字Synchronized: 当使用Synchrnized (o) ,锁定 o 的时候,锁定的是 o 指向的堆内存中 new 出来的对象,而非 o 引用,当锁定 o 以后,一旦 o 指向了其他对象 ...

  7. Java并发编程(四)synchronized

    一.synchronized同步方法或者同步块 在了解synchronized关键字的使用方法之前,我们先来看一个概念:互斥锁,顾名思义:能到达到互斥访问目的的锁. 举个简单的例子:如果对临界资源加上 ...

  8. 多线程之synchronized

    Java并发编程:synchronized 虽然多线程编程极大地提高了效率,但是也会带来一定的隐患.比如说两个线程同时往一个数据库表中插入不重复的数据,就可能会导致数据库中插入了相同的数据.今天我们就 ...

  9. 05 synchronized

    转载自:  Java并发编程:synchronized http://www.cnblogs.com/dolphin0520/p/3923737.html 前文中也有相关的详细描述:02 如何创建线程 ...

随机推荐

  1. 数据仓库模型之CDM、LDM与PDM的区别

    在数据仓库建设中,概念数据模型设计与逻辑数据模型设计.物理数据模型设计是数据库及数据仓库模型设计的三个主要步骤. conceptual data model 概念数据模型是最终用户对数据存储的看法,反 ...

  2. 万答#1,MySQL中如何查询某个表上的IS(意向共享)锁

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 问题 问题原文是这样的: 假如在MySQL事务里,给某个表的一行加了 共享锁,理 ...

  3. Sphere类定义

    这个类是球体,也就是一会要显示的球体了.这个类继承于Geometrics类,并实现了自己的碰撞检测,碰撞原理,书上也说的很清楚了啊,大家多看.然后对照代码就明白了. 类定义: #pragma once ...

  4. Java SE 9 多版本兼容 JAR 包示例

    Java SE 9 多版本兼容 JAR 包示例 作者:Grey 原文地址:Java SE 9 多版本兼容 JAR 包示例 说明 Java 9 版本中增强了Jar 包多版本字节码文件格式支持,也就是说在 ...

  5. java-数组排序之冒泡排序(经典排序)

    public class BubbleSort { public static void main(String[] args) { /*冒泡排序不一定是用时最短的 * 1)声明整型数组arr,包含1 ...

  6. python常量与变量的本质

    python语法常量与变量的本质 python语法之注释 1.python语法注释有哪几种? (1.)单行注释 # 井号键单行注释 使用方法:首先在另起一行按('#')井号键进行注释,如果需要代码后面 ...

  7. 「SHOI2014」概率充电器

    题面 n <= 500000   0<= p,qi <= 100 题解 这是道概率树形DP题,但是很难推怎么用加法原理和乘法原理正向求每个点被充电的概率,所以我们求每个点不被充电的概 ...

  8. React报错之Property 'value' does not exist on type EventTarget

    正文从这开始~ 总览 当event参数的类型不正确时,会产生"Property 'value' does not exist on type EventTarget"错误.为了解决 ...

  9. Linux虚拟机快捷键大全

    转发请注明原作者! 图形化命令框快捷键 Ctrl-Shift-t 创建标签页 Ctrl-Shift-w 关闭标签页 Ctrl-Shift-n 创建新窗口 Ctrl-Shift-q 关闭新窗口 Ctrl ...

  10. 变废为宝: 使用废旧手机实现实时监控方案(RTSP/RTMP方案)

    随着手机淘汰的速度越来越快,大多数手机功能性能很强劲就不再使用了,以大牛直播SDK现有方案为例,本文探讨下,如何用废旧手机实现实时监控方案(把手机当摄像头做监控之用): 本方案需要准备一个手机作为采集 ...