[JVM] Synchronized lock upgrade process

Table of contents

How to go from lock-free state to biased lock state:

Bias lock upgraded to lightweight lock:

From lightweight lock to spin lock state:

The spin lock is upgraded to a heavyweight lock:

The following is the process of upgrading a spin lock to a heavyweight lock:

The characteristics of heavyweight locks are as follows:


Synchronized locks are divided into three states - biased locks, lightweight locks, and heavyweight locks

How to go from lock-free state to biased lock state:

        When a thread accesses a code block modified by synchronized and acquires the object's lock, the thread's ID will be recorded in the Mark Word in the object header. This is It's called biased lock.

        If the thread ID recorded in the object's Mark Word is 0, it means that no thread currently acquires the lock, then record the thread's ID into the Mark Word and point the object head to the bias lock.

Bias lock upgraded to lightweight lock:

  • When other threads try to acquire a lock on an object, and the JVM finds that the thread ID pointed to by the object header is inconsistent with the current thread ID, it will try to upgrade the bias lock to a lightweight lock.
  • The JVM will also allocate space in Mark Word to store lock records (lock records include pointers, flags and other information)
  • The JVM will then use the CAS (Compare and Swap) operation to try to replace the biased lock in the object header with a pointer to the lock record, and record the thread ID into the lock record.
  • If the CAS operation succeeds, it means that the lock upgrade is successful, and the current thread enters the critical section and points to the code; if it fails, it means that there are other threads competing, and it may be further upgraded to a heavyweight lock.

From lightweight lock to spin lock state:

  1. Initial state: Assume there are two threads A and B. Thread A first obtains the lightweight lock of object obj and is executing the critical section code.
  2. Competition lock: Thread B also wants to acquire the lock of object obj, but finds that the lightweight lock has been acquired by thread A. At this time, thread B will enter the spin lock state.
  3. Spin lock waiting: After thread B enters the spin lock state, it will spin a certain number of times (i.e., loop retry) and continuously check whether the lightweight lock mark is released by thread A.
  4. Spin lock optimization: In the spin lock state, if thread A releases the lightweight lock in a short period of time, thread B can acquire the lock immediately without entering the blocking state. In this case, the spin lock avoids the overhead of thread context switching and improves performance.
  5. Spin lock wait timeout: If thread B still cannot obtain the lock after spinning a certain number of times, it will be considered that the competition is fierce, and it is unlikely that other threads will execute the critical section code. At this time, thread B will give up the spin lock and enter the blocking state, giving up the CPU execution rights and waiting for the lock to be released.
  6. Advantages of spin locks: Spin locks can improve performance when the critical section code execution time is short and thread competition is not intense, because thread context switching is avoided. However, if the execution time of the critical section code is long or the thread competition is fierce, using spin locks may waste CPU resources.

The spin lock is upgraded to a heavyweight lock:

        When a thread cannot obtain the lock in the spin lock state, it will upgrade to a heavyweight lock. A heavyweight lock is a blocking lock that causes the thread to enter a blocking state and release the CPU's execution rights.

The following is the process of upgrading a spin lock to a heavyweight lock:

  1. Spin lock waiting: Suppose there are two threads A and B. Thread A holds the spin lock of object obj and is executing the critical section code. Thread B tries to acquire the lock but fails and enters the spin state.
  2. Spin lock wait timeout: Thread B still cannot obtain the lock after a certain number of spins. At this time, thread B will give up the spin lock and hang itself, entering the blocking state.
  3. Lock upgrade: After thread B enters the blocking state, the JVM will upgrade the lock to a heavyweight lock. The characteristic of heavyweight locks is that they will cause the thread to enter a blocking state and release the CPU's execution rights.
  4. Thread blocking: After thread B is blocked, it will no longer try to acquire the lock until the lock is released. At this time, thread B will enter a state waiting to wake up.
  5. Lock release: When thread A finishes executing the critical section code, the lock will be released. At this time, the JVM will choose a blocked thread (such as thread B) to wake up and make it try to acquire the lock again.
  6. Thread wake-up: The awakened thread (such as thread B) will recover from the blocking state and start retrying to acquire the lock.

The characteristics of heavyweight locks are as follows:

  • High overhead: Threads using heavyweight locks will enter a blocking state, which will cause thread context switching overhead and affect performance.
  • Fairness: Heavyweight locks are usually fair, that is, the thread with the longest waiting time will be awakened first to ensure fairness.
  • Thread blocking: A thread that fails to acquire a heavyweight lock will enter a blocking state and will not consume CPU resources, waiting for the lock to be released.
  • Larger granularity: Heavyweight locks correspond to the entire object rather than a certain part of the object, so in the case of multi-thread competition, other threads will not be able to access the object.

        It should be noted that the process of upgrading to heavyweight locks is not static, and the specific implementation may have different strategies and optimizations. The specific behavior and performance of the lock also depends on

Guess you like

Origin blog.csdn.net/miles067/article/details/132757278