轻量锁

当第二个线程来加锁,会走轻量锁流程。先说明轻量锁加锁流程的核心,那就是CAS操作,CAS的对象就是lock record和对象头的mark word。看看JVM中的源码是如何写的

  1. if (!success) {
  2. //构造一个无锁不可偏向的markword
  3. markOop displaced = lockee->mark()->set_unlocked();
  4. //将无锁不可偏向的markword放到lock record中
  5. entry->lock()->set_displaced_header(displaced);
  6. //判断是否关闭了JVM轻量锁,一般不会关闭
  7. //如果指定了-XX:+UseHeavyMonitors,则call_vm=true,代表禁用偏向锁和轻量级锁
  8. bool call_vm = UseHeavyMonitors;
  9. //CAS操作,将对象头的mark word替换为指向Lock Record的指针
  10. if (call_vm || Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) {
  11. // Is it simple recursive case?
  12. if (!call_vm && THREAD->is_lock_owned((address) displaced->clear_lock_bits())) {
  13. entry->lock()->set_displaced_header(NULL);
  14. } else {
  15. CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception);
  16. }
  17. }
  18. }

CAS成功以后,会将lock record中的 displaced word 替换为对象头mark word,对象头的mark word 替换为指向lock record 的指针(62bit)+ 锁状态(001)。 再来看看轻量锁加锁流程