栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

synchronized

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

synchronized

synchronized

synchronized关键字被编译成字节码后,会被翻译成monitorenter和monitorexit两条指令,分别在同步块逻辑代码的起始位置和结束位置。
每个同步对象都有自己的Monitor。
1.使用Monitor.Enter得到对象Object的监视器锁,
2.如果Monitor.Enter成功执行同步业务
3.执行完业务释放锁 Moniter.Exit
4.如果第2步失败,把这次请求的线程放到同步队列中SynchronizedQueue中,当第三步执行完,出队列,再尝试获取锁。

当多个线程同时访问一段同步代码时:
1.首先会进入_EntryList集合,当线程获取到对象的monitor后,进入_Owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;
2.若线程调用wait方法,将释放当前持有的monitor,owner变量恢复为null,count减1,同时该线程进入WaitSet集合中等待被唤醒;
3.若当前线程执行完毕,也将释放monitor锁并复位count的值,以便其他线程进入获取monitor;

Monitor对象存在于每个java对象的对象头Mark Word中,Synchronized锁便是通过这种方式获取锁的,也是为什么Java中任意对象可以作为锁的原因,同时notify notifyAll wait等方法会使用到Monitor锁对象,所以必须在同步代码块中使用。

对象的内存布局

对象在内存中存储的布局可以分为三块区域:对象头、实例数据、对齐填充。
1.对象头:hash码,对象所属的年代,对象锁,锁状态标志偏向锁(线程)ID,偏向时间,数组长度(数组对象)等。java对象头一般占有2个机器码,但是如果对象是数组类型,则需要3个机器码,因为JVM虚拟机可以通过Java对象的元数据信息确定Java对象的大小,但是无法从数组的元数据来确定数组的大小,所以用一块来记录数组的长度。
2.实例数据:存放类的属性数据信息,包括父类的属性信息;
3.对齐填充:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅为了字节对齐。

Mark Word

对象头中的 MarkWord是实现轻量级锁和偏向锁的关键。

偏向锁

偏向锁是Java6之后加入的,它是一种针对枷锁操作的优化手段,在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,因此为了减少同一线程获取锁的代价而引入偏向锁。如果一个线程获得了偏向锁,那么锁就进入偏向模式,Mark Word的结构也变为偏向锁结构,当这个线程再次请求锁时,无需做任何同步操作。如果锁的竞争比较激烈,偏向锁就失效了,偏向锁失效后,先升级为轻量级锁

轻量级锁

如果偏向锁失效,虚拟机并不会立即升级为重量级锁,他先尝试一种轻量级锁的优化手段也是java6加入的,此时Mark Word的结构也变为轻量级锁的结构。轻量级锁适应的场景是线程交替执行同步块的场合,如果存在同一时间访问同一锁的场合,就会导致轻量级锁升级为重量级锁。

自旋锁

轻量级锁失败后,还会进行一项称为自旋锁的优化手段。如果经过自旋锁还不能获得锁,那就会将线程在操作系统层面挂起,就升级为重量级锁了。

锁消除

锁消除依据的是逃逸分析的数据支持。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/727531.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号