网站首页 > java教程 正文
java中任何对象都可以作为锁对象,对象包含markword、body、classword等。
对象头格式:
锁记录:加锁时线程栈帧中创建的一个对象,包含的字段有锁对象的引用(指针),锁对象的地址
每个锁对象可以关联一个jvm层次的Monitor对象,假设现在有两个线程分别为t0和t1。还是使用我们的synchronized关键字对临界区代码进行加锁。
假设目前t0加锁成功,并且t1没有与t0进行竞争,所以目前t0加上的锁是轻量级锁,将锁对象的markword字段与t0线程栈帧中锁记录地址CAS交换成功,锁对象的锁标志为轻量级锁。然后轻量级锁解锁时,再使用CAS交换t0线程栈帧中的锁对象的markword和和锁对象中的锁记录,交换成功则解锁。
上面解锁是在没有其他线程进行竞争情况下的流程,假如t1在t0上锁之后也请求该锁对象,也进行t1线程栈帧中锁记录地址CAS的交换,但是发现该锁对象的加锁状态为true,所以加锁失败,然后此锁对象的锁标志也升级为重量级锁,在t0解锁的时候发现锁已经升级为重量级锁,然后就将该锁对象的OWNER设置为空,唤醒entryList中受阻塞的线程。
自旋优化
重量级锁进行竞争时,会进行自旋优化以避免线程切换(切换为引起阻塞)。jdk1.7以后程序员无法控制是否开启自旋锁
偏向锁:
只有第一次使用CAS将线程id替换到对象markword中,之后该线程再次获取锁的时候发现是自己的线程id,就不需要进行cas替换操作占用cpu时间片。但是当业务中包含多个线程竞争一个锁时,就不适合使用偏向锁了。
而且调用一个对象的hashcode()方法会撤销该对象的偏向锁,将该对象的线程id信息替换为该对象的hashcode,是因为对象头没空间存储才撤销。轻量级锁和重量级锁都是与栈帧的锁记录进行交换的,所以不存在没空间存储的问题,调用他的hashcode方法当然也不会撤销轻量级锁或者重量级锁。
-XX:-useBiasedLocking表示禁用偏向锁,-XX:+useBiasedLocking表示开启偏向锁。
偏向锁撤销: 其他线程竞争时,会从偏向锁升级为轻量级锁。
锁消除:默认是打开的,使用-X:-elimiteLocks取消锁消除。jit会对代码进行逃逸分享,即使你加锁了,在发现该锁没有可能被多线程使用的情况会自动消除该锁。
猜你喜欢
- 2025-06-23 Java阻塞队列:LinkedTransferQueue
- 2025-06-23 Java面试题-锁的膨胀升级过程(锁的机制升降级)
- 2025-06-23 Java中CurrentHashMap的使用原理?
- 2025-06-23 Java并发锁机制和Atomic原理解析(java并发的时候常用的处理方式)
- 2025-06-23 「Java多线程」内置锁(Synchronized)的前世今生
- 2025-06-23 Java 面试题:乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
- 2025-06-23 万字详文:腾讯高可用、高性能 ZooKeeper 源码和实践揭秘
- 2025-06-23 ReentrantLock源码解析:ReentrantLock 的实现原理与 AQS 机制
- 2025-06-23 Java面试题整理:紧跟2025年面试趋势
- 2025-06-23 面试官:说一下 synchronized 锁机制原理 与 Lock 锁机制
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)