老师,关于偏向锁、轻量级锁、重量级锁的几个疑问?
来源:4-8 如果被问偏向锁、轻量级锁、重量级锁

hllcve
2021-06-01
- 偏向锁位的线程ID是什么时候取消设置的(即什么时候释放偏向锁), 是离开临界区的时候吗?
- 偏向锁和重量级锁是可以直接成为Owner, 而轻量级锁的作用只是为了进入EntrySet而并不能直接成为Owner?
- Owner线程进入wait后, 再次竞争时若偏向锁位置设置的线程ID为当前线程, 按这个图的流程并不会比较线程ID, 判断是不是当前线程, 而是直接进入到判断是否存在Owner线程, 那么这个偏向锁位的意义只是’是和否’, 具体的线程ID有何意义?
- EntrySet中只有一个会进行spin lock竞争, 且WaitSet中也有线程时, 可不可以理解成进行竞争时是EntrySet和WaitSet中各取其中一个线程进行竞争, 故同一时刻最多只要两个线程在竞争?
- 为什么一个持有锁的线程离开临界区后, 会重新进入WaitSet? 离开临界区不是说明线程的代码已经执行完毕了吗, 为什么还要进入到WaitSet, 加入到WaitSet后在下一轮竞争中如果抢到锁了, 后续操作是什么呢临界区中的代码不是都执行完了吗? 线程休眠后进入WaitSet是因为还有一部分代码没有执行完需要再次竞争后把时候剩下的执行完.
- 文档中有这么一句话, “进入EntrySet之后, 如果当前没有持有者, 就让这个线程去竞争.” 按这句话理解就是需要先进入到EntrySet之后再判断是否存在Owner线程然后在做后续操作, 而图中标红部分Y和N是两个分支(要么走Y要么走N), 即不进入到EntrySet也可以直接成为Owner或进入到WaitSet, 那么是文档中的描述错了还是图画错了, 按我的理解是图画错了?
写回答
1回答
-
都是这样,离开临界区释放锁。
偏向锁可以直接成为Owner;没有Owner的时候,轻量级锁可以直接成Owner;不能直接拿到Owner才会到重量级锁。 (现在Java偏向锁去掉了)。不过几个Owner描述不太一样,偏向锁直接有一个bit,轻量级锁+重量级锁是设置一个threadID。这个也很好理解,偏向锁目标就是在没有线程竞争的过程中用的。
EntrySet的设计是为了分流;WaitSet的设计是为了等待。EntrySet慢慢竞争总会进去,但是EntrySet本质上什么也不做,只不过每次从里面取出一部分来竞争锁(减少并发压力),任何线程竞争失败当然就直接去等待了。
同一时刻,有多少个线程想要竞争是不确定的。EntrySet的设计是为了减少这种压力,具体几个要看算法的实现。或者说几个都行,取出一部分竞争即可。简单来说,做JVM的人有具体数据,知道该如何操作在平均情况下性能较好。
离开临界区就不用再进入Wait了。如果是执行了一半wait了,就进入wait。
文档错了。 没有Owner才会触发竞争Owner。有Owner才会走EntrySet的机制。
总结下,现在Java在弱化偏向锁和轻量级锁。你可以看到当年Java设计这些锁是为了应对并发量较低的场景,现在并发量较低的场景性能再去微优化价值已经不大了。
112021-06-07
相似问题