JVM 内置锁 synchronized 详解

synchronized :
多线程编程中,有可能会出现多个线程同时访问同一个共享、
可变资源的情况,这个资源我们称之其为临界资源;
这种资源可能是:
对象、
变量、
文件等。
共享:
资源可以由多个线程同时访问
可变:
资源可以在其生命周期内被修改
引出的问题:
由于线程执行的过程是不可控的,
所以需要采用同步机制来协同对对象可变状态的访问!
那么问题来了,如何保证这种临界资源同一时间只有一个线程能访问呢---------当然就是加锁
在Java 中,主要有两种加锁方式 分别是synchronized、Lock
前者是JVM内置锁,后者是纯java语言开发的(底层也依赖了C语言)
加锁目的:
序列化访问临界资源,即同一时刻只能有一个线程访问临界资源(同步互斥访问)
不过有一点需要区别的是:当多个线程执行一个方法时,
该方法内部的局部变量并不是临界资源,因为这些局部变量是在每个线程的私有栈中,因此不具有共享性,不会导致线程安全问题。
synchronized原理详解
synchronized内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对象,是可重入锁

加锁的方式主要有下面几种:
1.作用于非静态方法,锁住的是对象实例(this),每一个对象实例有一个锁
public synchronized void method() {}
2.作用于静态方法,锁住的是类的Class对象,因为Class的相关数据存储在永久代元空间,元空间是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程。
public static synchronized void method() {}

3.加锁某一段代码块
synchronized (Lock.class) {
//需要加锁的代码块
}
或者
public static Object monitor = new Object();
synchronized (monitor) {
//需要加锁的代码块
}

synchronized底层原理
synchronized是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,
监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现,它是一个重量级锁性能较低。当然,
JVM内置锁在1.5之后版本做了重大的优化,如锁粗化(Lock Coarsening)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)、
适应性自旋(Adaptive Spinning)等技术来减少锁操作的开销,内置锁的并发性能已经基本与Lock持平。
synchronized关键字被编译成字节码后会被翻译成monitorenter 和 monitorexit 两条指令分别在同步块逻辑代码的起始位置 与结束位置。
在这里插入图片描述
每个同步对象都有一个自己的Monitor(监视器锁)
Monitor监视器锁
任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。Synchronized在JVM里的实现都是基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter和MonitorExit指令来实现。
Synchronized的语义底层是通过一个monitor的对象来
完成,其实wait/notify等方法也依赖于monitor对象。
什么是monitor?
可以把它理解为一个同步工具,也可以描述为一种同步机制,
它通常被描述为一个对象。与一切皆对象一样,所有的Java对象是天生的Monitor,每一个Java对象都有成为Monitor的潜质,因为在Java的设计中,每一个Java对象自打娘胎里出来就带了一把看不见的锁,它叫做内部锁或者Monitor锁。也就是通常说Synchronized的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor实现的。
既然synchronized 加锁是加在对象上的,那么如何知道锁的状态呢?
其实:锁的状态是记录在对象的对象头上的HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
对象头除了记录锁的状态之外,还记录着哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、
偏向线程ID、偏向时间戳。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值