学习这块的时候刚开始觉得有点理解,结果越想越懵,还是理解的不够,这边有几个疑问
场景1:如果当前临界区只有一个线程,那么当前对象是偏向锁,如果有一个新的线程进入临界区,锁将自旋变成轻量锁。
①这里变成轻量锁的操作是持有锁的线程做的,还是正在自旋的线程做的?
②如果锁升级成轻量级锁,对象头发生了变化,那持有锁的的线程里的对象的对象头也会发生变化么?【同一个对象在不同线程里的对象头是否是一致的】
场景2:锁膨胀为重量级锁
①如果占用资源的一个线程释放了锁,那对象头会发生什么样的变化呢?
偏向锁: Hotspot的作者经过以往的研究发现大多数情况下锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。适用于一个线程访问同步代码块的场景。
轻量级锁: 用于竞争不是很激烈或同步代码块执行很快的场景,它不会阻塞,而是自旋。(自旋几次还没获取到锁升级为重量级锁)
轻量级锁自旋几次后还没得到锁(自旋可以理解为循环),不管几个线程都会膨胀。
0元创业http://www.danews.cc/tech/chuangye/2019/0308/2646.html
顾名思义,轻量级锁是相对于重量级锁而言的。使用轻量级锁时,不需要申请互斥量,仅仅将Mark Word中的部分字节CAS更新指向线程栈中的Lock Record,如果更新成功,则轻量级锁获取成功,记录锁状态为轻量级锁;
自旋是java重量级锁的一种状态(当多次自旋之后,切换到内核态park)。
这边问题1有些奇怪。 当发生竞争的时候轻量级锁会变成重量级锁。 这边原来是偏向锁的话,碰到有其他线程访问,会变成轻量级锁(注意这里并没有发生竞争)。 这个必然是非own 线程的另一个线程修改偏向锁。
问题2 : 请注意对象并非是栈区分配的,是堆区的,对于堆区是每个线程值都是一样的(不考虑短时间内的不可见性)。
场景2: 重量级锁,对象头其实就没啥用了,指向的是底层的独享。实际就是cpp 的mutex。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。