在多线程环境下,当你的转账操作被重复提交💸、库存被超卖📉、计数器结果离奇错误❌时,背后往往是因为缺乏合理的锁控制。而悲观锁作为Java并发中最「简单粗暴」的解决方案,从JDK1.0时代的重量级锁⛓️,到如今JVM层级的锁升级优化⚡,其底层实现堪称一部高性能并发的发展史📜。
本文将带你穿透**synchronized
关键字**的表面语法,直击三大核心问题💡:
synchronized
如何实现性能飞跃?**(偏向锁/轻量级锁的取舍智慧)📌 举个真实案例:某电商平台在秒杀活动中使用synchronized
导致TPS从8000📈暴跌到300📉,最终通过缩小锁粒度+锁分离优化提升15倍性能🚀——我们将在文中用代码还原这个优化过程。
下面我们直接切入正题,从操作系统与JVM的协作契约🤝开始讲起!
悲观锁:假设其他线程会修改共享资源,在进入同步代码块时就加上锁,防止其他线程的干扰。但是如果竞争激烈,就会发生线程上下文切换,性能相对低。
synchronized
关键字,基于Monitor实现,用于实现多线程之间的同步,是悲观锁
synchronized
的执行流程:
synchronized
的特性:
synchronized
保证同时只能有一个线程执行同步代码块,对共享数据的操作是原子的。synchronized
同步代码块时,会先获取主内存中的数据到工作内存中,修改共享资源,退出同步代码块时,会将工作内存中的数据刷新到主内存中,保证数据的可见性。synchronized
会禁止JVM对字节码指令重排优化,保证线程执行的有序性。synchronized
的作用范围:
synchronized
修饰成员方法时,锁住的是当前对象实例。synchronized
修饰静态方法时,锁定的是当前类的Class对象。synchronized
修饰代码块时,锁定的是指定的对象。多线程只有获取同一个对象的锁才能起到同步互斥的效果
JDK1.6之前synchronized是重量级锁,jdk1.6之后对synchronized做了一系列优化,加入了偏向锁和轻量级锁,优化了线程上下文切换的性能
synchronized是悲观锁,在操作共享资源之前需要先加锁,加的锁就存在于Java对象头中.
Hotspot虚拟机中的对象头主要包含两部分数据:Mark Word(标记字段)和Klass Pointer(类型指针)
Monitor是一种同步机制,依赖于操作系统底层的Mutex Lock(同步锁)来实现同步,在Java中,每一个Java对象都会关联一个Monitor对象,synchronized关键字就是通过Monitor来实现线程同步的,是重量级锁
Monitor的组成部分:
Monitor的执行流程:
synchronized
代码块的线程,首先尝试获取对象锁,如果锁是空闲状态,则获取到锁,成为owner。如果锁已被其他线程占用,则进入阻塞synchronized
代码块的线程尝试获取对象锁未成功,处于阻塞状态,进入EntryList队列,等待对象锁的释放synchronized
代码块执行完毕后,会释放该对象锁,同时唤醒EntryList中阻塞的线程来竞争对象锁,竞争成功的线程成为新的owner,失败的线程则继续等待扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有