进程,线程04

Monitor 对象
  • 任何对象都关联了一个管程,管程就是控制对象并发访问的一种机制。
  • 可以理解 synchronized 就是 Java 中对管程的实现。管程提供了一种排他访问机制,这种机制也就是互斥。互斥保证了在每个时间点上,
  • 最多只有一个线程会执行同步方法。所以理解了 Monitor 对象其实就是使用管程控制同步访问的一种对象。
  • monitor对象是monitor机制的核心,它本质上是jvm用c语言定义的一个数据类型。对应的数据结构保存了线程同步所需的信息,比如保存了被阻塞的线程的列表,还维护了一个基于mutex的锁,monitor的线程互斥就是通过mutex互斥锁实现的。
synchronized底层语义原理

Synchronized是通过对象内部的一个叫做监视器锁monitor来实现的,监视器锁本质又是依赖于底层的操作系统的Mutex Lock互斥锁来实现的。而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。因此,这种依赖于操作系统Mutex Lock所实现的锁称之为重量级锁。
Java SE 1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”:锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态。锁可以升级但不能降级。
偏向锁是JDK1.6中引用的优化,它的目的是消除数据在无竞争情况下的同步
原语,进一步提高程序的性能。
轻量级锁也是在JDK1.6中引入的新型锁机制。它不是用来替换重量级锁的,它的本意是在没有多线程竞争的情况下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗
Synchronized的重量级锁是通过对象内部的一个叫做监视器锁monitor来实现的,监视器锁本质又是依赖于底层的操作系统的Mutex Lock互斥锁来实的。而操作系统实现线程之间的切换需要从用户态转换到核心态,这个成本非常高,状态之间的转换需要相对比较长的时间,这就是为什么Synchronized效率低的原因。
对于synchronized语句当Java源代码被javac编译成bytecode的时候,会在同步代码块的入口位置和退出位置分别插入monitorenter和monitorexit(2个)字节码指令。而synchronized方法则会被翻译成普通的方法调用和返回指令,在VM字节码层面并没有任何特别的指令来实现被synchronized修饰的方法,而是在Class文件的方法表中将该方法的access_flags字段中的synchronized标志位置1,表示该方法是同步方法并使用调用该方法的对象或该方法所属的Class在JVM的内部对象表示Class做为锁对象
执行monitorenter指令时,线程会为锁对象关联一个ObjectMonitor对象(c++)。
线程遇到synchronized同步时,先会进入ObjectMonitor对象的EntryList队列中然后尝试把ObjectMonitor对象的owner变量设置为当前线程,同时ObjectMonitor对象的monitor中的计数器count加1,即获得对象锁。否则通过尝试自旋一定次数加锁,失败则进入ObjectMonitor对象的cxq队列阻塞等待
synchronized是可重入,非公平锁,因为entryList的线程会先自旋尝试加锁,而不是加入cxq排队等待,不公平
官方文档 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11.10

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值