Synchronized Lock Escalation in Java


1. Java object structure

The structure of a Java object is divided into three parts, namely the object header, object body and alignment bytes. The lock used by synchronized exists in the Java object header, so what is the object header?

Let's take the Hotspot virtual machine as an example. The Hopspot object header mainly includes two parts of data: Mark Word (mark field) and Klass Pointer (type pointer).

  • Mark Word: mainly used to store its own runtime data
  • Class Pointer: It is a pointer to the object of the class in the method area. The JVM uses this field to determine which class the current object is an instance of

The "runtime data" represented by Mark Word is mainly used to indicate the thread lock status of the current Java object and the GC flag. The thread lock states are no lock, biased lock, lightweight lock, and heavyweight lock.
insert image description here

2. Lock status

  1. Lock-free
    Lock-free means that no resource is locked, all threads can access and modify the same resource, but only one thread can modify it
    successfully.


  2. When thread A executes the synchronized code block for the first time in the state of bias lock and lock-free, the lock object becomes a bias lock. After executing the synchronized code block, the thread will not actively release the bias lock . Any check needs to be done and executed directly (biased to the first thread to obtain it), which reduces the cost of acquiring locks and improves efficiency.
    The lock flags of no lock and biased lock are the same, that is, they are both 01. No lock and biased lock are distinguished by the field biased_lock. 0 means that biased lock is not used, and 1 means that biased lock is enabled.

  3. Lightweight lock
    In the process of upgrading to a biased lock, once a second thread participates in the competition, it will immediately expand into a lightweight lock. The thread attempting to preempt will initially use the spin method to try to acquire the lock. If the loop is repeated several times and other threads release the lock, there is no need to switch from user mode to kernel mode.
    Before JDK 1.7, it was normal spin, which would set a maximum number of spins, the default is 10 times, and the spin will stop when this threshold is exceeded. After JDK 1.7, adaptive spin was introduced. If the spin acquires the lock this time, the number of spins will increase; if the spin does not acquire the lock this time, the number of spins will decrease.

  4. Heavyweight lock
    In the process of upgrading to a lightweight lock, if the spin of the thread trying to preempt reaches the threshold, it will stop spinning, and then the lock will expand into a heavyweight lock at this time. When it expands into a heavyweight lock, other competing threads will not spin when they come in, but will block and wait directly, and the content in Mark Word will become a monitor (monitor) object, which is used to uniformly manage the queuing thread.

3. How does the monitor object manage threads

Each java object can be associated with a monitor object. If synchronized is used to add heavyweight locks, the monitor address will be stored in the Mark word to associate with the monitor object.
insert image description here

  • Owner : The thread that owns the current monitor object, that is, the thread that holds the lock.
  • WaitSet : When the Owner thread calls the wait() method and is blocked, it will be placed here. When the waiting time expires, or other threads wake up, they will re-enter the EntryList.
  • EntryList: All threads competing for locks will enter the ContentionQueue first, and the eligible threads in the ContentionQueue will be moved here.

4. Lock Upgrade

Thread A enters synchronized and starts to grab the lock. The JVM will judge whether it is currently in a biased lock state. If it is, it will judge whether the current thread A is the thread holding the biased lock according to the thread ID stored in the Mark Word. If yes, check is ignored, and thread A directly executes the code in the critical section.

But if the thread in Mark Word is not thread A, it will try to acquire the lock by spinning. If it is acquired, it will change the thread ID in Mark Word to its own; if the competition fails, it will immediately revoke the biased lock, expanding to Lightweight lock.

Subsequent competing threads will try to acquire the lock by spinning. If the spin is successful, the state of the lock is still a lightweight lock. However, if the competition fails, the lock will expand into a heavyweight lock, and subsequent competing threads that are waiting will be blocked.
insert image description here

Guess you like

Origin blog.csdn.net/weixin_44153131/article/details/129800422