Java并发机制的底层实现原理--synchronized

Java并发机制的底层实现原理–synchronized

synchronized的应用

关键词:重量级锁,偏向锁,轻量级锁,java对象头
问题:什么是“锁”?
	1.锁。java中每一个对象都可以作为锁。
		1.1,普通同步方法,锁是当前实例对象
		1.2,静态同步方法,锁是当前class对象
		1.3,同步方法块,锁是Synchronized括号里配置的对象

问题:“锁”有什么作用?
	当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放	锁。
	
问题:得到“锁”是得到锁住的这个对象吗?
	不是。JVM是基于进入和退出Monitor对象来实现方法的同步和代码块的同步的。代码块的
	同步是使用monitorenter(插入同步代码块的开始位置)和monitorexit(插入同步代码块的
	结束和异常处)指令实现的,而方法同步是使用另一种方式实现的,细节JVM里面没有详细
	说明。JVM保证每个monitorenter都有对应的monitorexit进行配对,任何一个对象都有一个
	monitor与之管关联,当一个monitor被持有后,它将处于被锁定状态,线程得到
	monitorenter指令时,将会尝试获取对象所对应的monitor所有权,即尝试获取对象的锁。
	得到“锁”--->得到monitor的所有权

问题:“锁”存放在哪里?
	Synchronized用的锁存在java对象头里,在32位虚拟机中,1字宽等于4字节(32bit)。如
	果对象是数组类型,在该虚拟机中用3个字宽存储对象头。非数组类型,用2字宽存储对象
	头。

问题:“java对象头”中存放着的是什么信息?
	非数组对象:Mark Word(1字宽),Class Metadata Address(1字宽)
	数组对象:非数组对象基础上+(Array length(1字宽))
	其中Mark Word存放有锁信息。

问题:Mark Word是什么结构?
	32bit结构如下:
锁状态25bit4bit1bit是否偏向锁2bit锁标志位
无锁状态对象的hashCode对象的分代年龄001

​ 64bit结构如下

锁状态25bit31bit1bit4bit1bit2bit
无锁unusehashCode001
偏向锁ThreadID(54bit)Epoch(2bit)101
	32bit结构的Mark Word状态变化如下
锁状态25bit4bit1bit2bit
轻量级锁记录栈中锁记录的指针(30bit)00
重量级锁指向互斥量(重量级锁)的指针(30bit)10
GC标记空(30bit)11
偏向锁线程ID(23bit)Epoch(2bit)分代对象年龄(4bit)101

锁的升级与对比

前言: JavaSE1.6中,锁一共有4中状态,级别从低到高依次。无锁状态,偏向锁
状态,轻量级锁状态,重量级锁状态。锁会随着竞争状况逐渐升级(不能降级)

问题:偏向锁诞生的原因?
大多数情况下,锁不仅不存在多线程竞争,而且总是同一线程多次获得。

问题:偏向锁的作用?
当一个线程访问同步代码块并获取锁时,会在对象头和栈帧的锁记录存储该线
程ID,以后该线程进入和退出同步代码块时不需要进行加锁和解锁操作,只需
检测对象头里的Mark Word里是否存储着指向当前线程的偏向锁(成功–>获得
锁)

偏向锁

问题:轻量级锁诞生的原因?
当应用程序里的锁绝大多数处于竞争关系时,偏向锁每次处理这样的线程都需
要切换偏向锁的值,效率产生影响,

轻量级锁

锁的优缺点对比

优点缺点适用范围
偏向锁加锁和解锁不需要额外的消耗,和执行非同步方法相比仅存在纳秒级的差距如果线程之间存在锁竞争,会带来额外的锁撤销消耗适用于只有一个线程访问同步块的场景
轻量级锁竞争的线程不会阻塞,提高程序的响应速度如果始终得不到锁竞争的线程使用自旋消耗CPU追求响应时间同步执行速度非常快
重量级锁线程竞争不使用自旋,不会消耗CPU线程阻塞,响应时间缓慢追求吞吐量,同步执行速度较长
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值