深入JVM内置锁|深入JVM内置锁 synchronized 底层
前言
上一章节带着大家了解了Java对象头的组成,本节带着大家了解synchronized 关键字的底层原理以及锁的升级过程
synchronized原理详解
【深入JVM内置锁|深入JVM内置锁 synchronized 底层】synchronized
内置锁是一种对象锁(锁的是对象而非引用),作用粒度是对象,可以用来实现对临界资源的同步互斥访问,是可重入的
什么是Monitor
在Java虚拟机(HotSpot)中,Monitor是由ObjectMonitor实现的。Synchronized
的对象锁,MarkWord锁标识位为10,其中指针指向的是Monitor对象的起始地址。其主要数据结构如下
ObjectMonitor() {
_header= NULL;
_count= 0;
// 记录个数
_waiters= 0,
_recursions= 0;
_object= NULL;
_owner= NULL;
_WaitSet= NULL;
// 处于wait状态的线程,会被加入到_WaitSet
_WaitSetLock= 0 ;
_Responsible= NULL ;
_succ= NULL ;
_cxq= NULL ;
FreeNext= NULL ;
_EntryList= NULL ;
// 处于等待锁block状态的线程,会被加入到该列表
_SpinFreq= 0 ;
_SpinClock= 0 ;
OwnerIsThread = 0 ;
}
ObjectMonitor中有两个队列,_WaitSet 和 _EntryList,用来保存ObjectWaiter对象列表( 每个等待锁的线程都会被封装成ObjectWaiter对象 ),_owner指向持有ObjectMonitor对象的线程,当多个线程同时访问一段同步代码时:
- 首先会进入 _EntryList 集合,当线程获取到对象的monitor后,进入 _Owner区域并把monitor中的owner变量设置为当前线程,同时monitor中的计数器count加1;
- 若线程调用 wait() 方法,将释放当前持有的monitor,owner变量恢复为null,count自减1,同时该线程进入 WaitSet集合中等待被唤醒;
- 若当前线程执行完毕,也将释放monitor(锁)并复位count的值,以便其他线程进入获取monitor(锁);
每个同步对象都有一个自己的Monitor(监视器锁):
文章图片
synchronized锁的升级过程
public class Test04 {
private static Object objectLock = new Object();
public static void main(String[] args) throws InterruptedException {
//-XX:BiasedLockingStartupDelay=0 强制开启
//System.out.println(">>----------------无锁状态001-------------------<<");
System.out.println(ClassLayout.parseInstance(objectLock).toPrintable());
System.out.println("开启了偏向锁,但是偏向锁没有关联偏向锁线程");
synchronized(objectLock){
// 偏向锁 关联偏向锁线程
System.out.println("开启了偏向锁,偏向是给我们的主线程");
System.out.println(ClassLayout.parseInstance(objectLock).toPrintable());
}
// 撤销偏向锁 是另外一个线程与偏向锁线程竞争
new Thread(new Runnable() {
@Override
public void run() {
synchronized (objectLock) {
try {
System.out.println(ClassLayout.parseInstance(objectLock).toPrintable());
Thread.sleep(5000);
System.out.println("子线程:升级为轻量级锁");
} catch (Exception e) {}
}
}
}, "子线程1").start();
Thread.sleep(1000);
sync();
}public static void sync() throws InterruptedException {
System.out.println(" 主线程获取锁 重量级别锁");
//11010000 01000000
synchronized (objectLock) {
System.out.println(ClassLayout.parseInstance(objectLock).toPrintable());
}
}}
文章图片
总结 本文主要介绍了synchronized底层原理
推荐阅读
- 如何使用Wordfence Security免费保护WordPress网站(深入指南)
- Android 使用内置的Camera应用程序捕获图像
- 多项logistic回归系数解释_深入解读Logistic回归结果(一)(回归系数,OR)
- Android深入四大组件Service的绑定过程
- 计算机图形绘画算法
- Android深入四大组件Service的启动过程
- Android开发艺术探索——第七章(Android动画深入分析)
- android 消息传递机制EventBus的深入探究
- 深入理解Android的startservice和bindservice
- Android开发之深入理解Android Studio构建文件build.gradle配置