synchronized锁底层实现原理

概要:在最初的时候,synchronized是一种重量级锁,在加锁的时候需要操作系统在内核访问核心资源,会进行状态的来回转换,效率很低,在JDK1.6之后,引入的偏向锁和轻量级锁,根据线程竞争情况对锁进行升级,在线程竞争不激烈的情况避免使用重量级锁

无锁:对象头中有31bit的空间来存储对象的hashcode,4bit用于存放对象分代年龄,1bit来表示是否是偏向锁,2bit存放锁标志位,偏向锁位与锁标志位合起来“001”就代表无锁。无锁就是没有对任何资源进行锁定,所有线程都能访问并修改资源。

偏向锁:对象头中记录了获得偏向锁的线程ID,偏向锁与锁标志位合起来“101”就代表偏向锁。有研究发现,在大多数情况下,锁很少被多个线程同时竞争,而且总是由同一个线程多次获得,因此只需要将获得锁的线程ID写入到锁对象Mark Word中,相当于告诉其他线程,这块资源已经被我占了。当线程访问资源结束后,不会主动释放偏向锁,当线程再次需要访问资源时,JVM就会通过Mark Word中记录的线程ID判断是否是当前线程,如果是,则继续访问资源。所以,在没有其他线程参与竞争时,锁就一直偏向被当前线程持有,当前线程就可以一直占用资源或者执行代码。

自旋锁(轻量级锁):一旦有另外一个线程参与锁竞争,偏向锁就会升级为自旋锁,此时撤销偏向锁,锁标志位变为“00”。竞争的两个线程都在各自的线程栈帧中生成一个Lock Record空间,用于存储锁对象目前Mark Word的拷贝,用CAS操作将Mark Word设置为指向自己这个线程的LR(Lock Record)指针,设置成功者获得锁,其他参与竞争的线程如果未获取到锁,则会一直处于自旋等待的状态,直到竞争到锁。


重量级锁:长时间的自旋操作是很消耗CPU资源的,为了避免这种盲目的消耗,JVM会在有线程超过10次自旋,或者自旋次数超过CPU核数的一半(JDK1.6以后加入了自适应自旋-Adaptive Self Spinning,由JVM自己控制自旋次数)时,会升级到重量级锁。重量级锁底层是依赖操作系统的mutex互斥锁,也就是有操作系统来负责线程间的调度。重量级锁减少了自旋锁带来的CPU消耗,但是由于操作系统调度线程带来的线程阻塞会使程序响应速度变慢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值