深入理解synchronized的使用及底层原理

synchronized的使用:
修饰方法:此时锁住的是当前对象实例
在这里插入图片描述
修饰静态方法:锁住的是当前类的c lass对象,因为一个类只有一个class对象,所以synchronized加在静态方法上,相当于该类的一个全局锁。
在这里插入图片描述
修饰代码块:锁住的是obj对象,作用在代码块中
在这里插入图片描述
synchronized原理:synchronized的同步是基于进入和退出monitor对象实现
sychronized修饰代码块反编译如下:
在这里插入图片描述
我们发现了monitorenter和monitorexit这两条指令,JVM规范中描述:
monitorenter:每个对象都有一个monitor监视器锁,当monitor被占用就会处于锁定状态。线程执行monitorenter指令就会尝试获取monitor的使用权:
步骤如下:
1.如果monitor进入数为0,当前线程进入monitor,进入数设为1,该线程设为monitor的持有者。
2.如果该线程已经占用monitor,只是重入,monitor进入数加1.
3.如果monitor已经被其他线程持有,当前线程阻塞,直到monitor进入数为0,该线程重新尝试获取monitor使用权。
monitorexit:执行该指令的必须是持有monitor的线程
指令执行时,monitor的进入数减1,如果减1后进入数为0,其他被这个monitor阻塞的线程可以重新尝试获取monitor的使用权。
synchronized修饰方法:反编译如下:
在这里插入图片描述
可以看到同步方法并不是通过moniterenter与monitorexit指令来实现同步的,而是通过方法调用指令读取运行时常量池的方法的标志位ACC-SYCHRONIZED来隐式实现的。具体步骤如下:
JVM通过标识符实现同步,方法调用时,调用指令会检查该方法是否有ACC-SYCHRONIZED标志位,如果有,当前线程将获取到monitor,获取成功后才能执行方法体,,执行完释放,执行期间,其他线程无法获取到同一个monitor对象。
对象监视器(monitor)的几种状态:
当有多个线程同时请求monitor时,monitor通过以下几种状态来区分线程:
1.Contention List:将所有请求监视器的线程放入竞争队列中。
2.Entry List:将COntentionList中有资格成为候选人的放入Entry List中。
3.Wait Set::存放那些调用了wait()阻塞的线程。
4.OnDeck:任何时刻最多只有一个线程竞争锁,该线程成为OnDeck;
5.owner:表示竞争到锁的线程
6.!owner:释放锁的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值