前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发基础之Synchronized原理

并发基础之Synchronized原理

作者头像
崩天的勾玉
发布2021-12-20 17:33:22
2660
发布2021-12-20 17:33:22
举报
文章被收录于专栏:崩天的勾玉

上篇文章和大家聊了聊hashmap和concurrenthashmap的结构、用法、原理,从这篇文章开始次我们来聊聊并发编程吧!本次我将带大家了解一下synchronized的原理。

synchronized从1.6优化了之后并不是上来就很重,而是有了多个锁状态,分别是偏向锁、轻量级锁、重量级锁。

1)「重量级锁」

synchronized是依赖jvm实现同步的,他在同步代码块里和同步方法的原理有一些区别: 1、同步代码块:通过monitorenter和monitorexit指令实现的,每个对象都有一个监视器锁monitor,monitor被占用的时候就说明这个对象处于一个锁定状态,而monitorenter指令的作用就是去获取这个monitor的所有权,monitorexit指令就是去释放monitor。我来说一下他们的机制: monitorenter:每个monitor有个进入数,当它为0的时候表示没有线程在占用,当前线程就可以进入monitor,并将进入数设置为1;那如果当前线程已经拥有这个monitor,又重新进入的话,进入数就会+1,这就是锁的重入;如果monitor已经被其他线程占有,那么当前线程进入阻塞状态,等待monitor被释放,再去尝试获取。 monitorexit:首先必须要拥有这个monitor才能去执行monitorexit,执行后进入数-1,如果到0了就退出这个monitor,不再拥有。其他线程可以尝试去获取。 2、同步方法:方法常量池中会多一个ACC_SYNCHRONIZED标识,调用方法的调用指令会让线程去获取monitor,获取成功的话再继续执行方法,方法执行完毕后再释放monitor,同一个monitor同一时刻只能被一个线程拥有。 「总结」:二者都需要获取和释放monitor来实现线程同步,monitor的实现依赖于操作系统的mutex互斥锁,操作系统的线程之间的切换需要从用户态切换到内核态,开销比较大。

「2)轻量级锁」

相对于使用mutex的重量级锁来说的,他的实现主要是基于对象头的mark Word,线程进入同步方法或者同步代码块的时候,如果同步对象处于无锁状态(锁标志位为"01"状态,是否为偏向锁为"0),那么虚拟机会在栈帧里建立一个lock record(锁记录),获取锁的时候会把对象头的mark Word给拷贝过来,然后通过CAS操作把mark Word 更新为指向lock record的指针,更新成功后就拥有了该对象的锁,并把锁标志位改为00(轻量级锁)。 更新失败会检查mark Word是否是指向当前线程的,是的话表示当前线程已经有了这个对象的锁,然后进入代码块里执行。否则的话就表示已经被其他线程抢占了,然后就进入一个自旋,再次尝试cas更新指针。如果自旋结束还是没获取锁,那就膨胀为重量级锁,锁标志位状态值变为"10",Mark Word中储存就是指向monitor对象的指针,当前线程以及后面等待锁的线程也要进入阻塞状态。 释放锁就是通过cas将lock record里拷贝的markWord给替换回去,替换成功进入无锁状态;失败说明有其他线程尝试获取该锁(此时锁已膨胀),那就要在释放锁的同时,唤醒被挂起的线程。

「3)偏向锁」

如果说轻量级锁是在无竞争的情况下使用CAS操作区消除同步使用的互斥量,那么偏向锁就是把整个同步都消除掉. 检查Mark Word是否为可偏向锁的状态,即是否偏向锁即为1即表示支持可偏向锁,否则为0表示不支持可偏向锁。如果是可偏向锁,则检查Mark Word储存的线程ID是否为当前线程ID,如果是则执行同步块。如果检查到Mark Word的ID不是本线程的ID,则通过CAS操作去修改线程ID修改成本线程的ID,如果修改成功则执行同步代码块,否则执行步骤4。当拥有该锁的线程到达安全点之后,挂起这个线程,升级为轻量级锁。 释放: 偏向锁的释放采用了一种只有竞争才会释放锁的机制,线程是不会主动去释放偏向锁,需要等待其他线程来竞争。然后等待全局安全点(在这个是时间点上没有字节码正在执行)。暂停拥有偏向锁的线程,检查持有偏向锁的线程是否活着,如果不处于活动状态,则将对象头设置为无锁状态,否则设置为被锁定状态。如果锁对象处于无锁状态,则恢复到无锁状态(01),以允许其他线程竞争,如果锁对象处于锁定状态,则挂起持有偏向锁的线程,并将对象头Mark Word的锁记录指针改成当前线程的锁记录,锁升级为轻量级锁状态(00)。

比较

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 崩天的勾玉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档