Synchronized 你了解多少

8 篇文章 0 订阅

对于我们开发者来说,Synchronized 最熟悉了,那么你真正了解它吗?

Synchronized 给我们第一印象就是加锁,其实Synchronized  做了很多优化,现在也是性能很好的锁机制。首先有必要了解Synchronized 的锁对象,对于Synchronized 在普通方法上,这种是锁为当前对象也就是this,如果修饰静态方法Synchronized修饰的为当前类的class ,同时我们还有普通的一种锁,那就是任何对象都可以作为Synchronized的锁。Synchronized 其实是一种可重入,排它锁(独享锁),悲观锁,同时他对于线程是可见的,资源不能进行cpu告诉缓存。那么它是怎么样一个工作原理呢?其他线程怎么知道这个对象上有锁了的呢?

其实上图就是我们对象执行的一个过程,其实我们都知道对象对象存储在堆内存中,在对内存中,对象是以属性格式进行存储,这是我们的jvm 运行时的数据分布,我们的类元数据存储在方法区中,而我们的变量地址引用存储在局部变量表中,那么我们如果增加Synchronized关键字,默认情况下一个线程会进行未锁定->偏向锁->轻量级所->重量级所升级。如果一个线程加锁,其他线程怎么知道其加锁,这些问题我们可以看我们堆中对象存储的格式可以看出,在我们的对象数据中有一个对象头:

其实上图就是我们jdk 对于Synchronized 锁的优化及使用什么类型的锁。线程是否获得锁,有一个监视器monitor进行监控,如果tag 为01,有可能锁定,可能未锁定,我们根据状态进行锁的判定。如果表示未锁定状态。

轻量级锁:

 

比如多线程竞争锁,线程1 通过CAS方式抢到了锁,如上图,将00标识到对象头中,那么其他线程不能得到其锁,进行一定的自旋处理。那么此时获得了一个轻量级锁。将我们状态标识位前存储我们的获取锁的线程引用。通过CAS操作获取相关的锁,并且存储其线程引用,这种方式我们叫做获取了轻量级的锁。

那么在过程中我们可以进行锁升级,从上图可以看出我们从轻量级锁进行锁升级,那么我们状态位通过CAS更新为10状态,将我们的线程地址此时更改为我们对象监视器地址,右边为我们的监视器进行锁获取的机制,可以看到当我们线程1获取锁之后,在monitor中owner 属性为线程1,那么此时如果其他线程进行锁获取时,判断出此时owner为线程1,那么它将会被存入我们监视器的entrylist 队列中,如果线程1调用了wait 方法时,那么线程1将会被存储到waitset 属性队列中去,那么entrylist 中线程就会进行锁的争抢。并不是调用wait 之后就会立马释放锁,这要根据我们cpu 及monitor 决定,当我们线程1进行unlock时,锁释放。

偏向锁如上图:如果对象位字段标志为01,并且将我们hashcode 替换为我们线程ID引用,那么此时我们说该线程获取了偏向锁。

对于更详细的可以查看JVM官方资料:https://wiki.openjdk.java.net/display/HotSpot/Synchronization

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值