Following on from the previous article, how do you understand Synchronized? (3), this article to talk about the implementation of synchronized lightweight lock upgrade.
4.2 Lightweight Lock
The previous section described two threads competing for a lock, leading to a partial lock cancellation. A common type of lock escalation during the cancellation process is to upgrade to a lightweight lock. Lightweight locking is suitable for scenarios where two threads compete for lock resources and synchronized code blocks execute quickly. So what happens to the Markword store layout in the object?
4.2.1 Lightweight Upgrade Process
It is well known that in the JVM, stacks are thread private. The first step in upgrading to a lightweight lock is to do things in the stack frame.
- Stack frame new create lock record
LockRecord
, included in the recordsdisplaced hdr
和owner
. - Locks the header of the object
Markword
The content is copied to the stack frame you just createdLockRecord
. - Record the lock
LockRecord
The owner in points to the lock object. - Finally put the object header
Markword
The pointer to the stack lock record in theLockRecord
(This step isMarkword
Store real changes to content).
The change process is shown in the figure below.
4.2.2 Lightweight competition process
When a thread holds a lightweight lock, it waits in an empty loop while another thread contests, rather than changing its state to Blocked. When the holding thread leaves the block and releases the lock, another thread quickly acquires the lock.
So why do threads that do not acquire lock resources wait in a loop instead of blocking? The most important reason is that thread blocking and wake up need CPU from user state to kernel state, frequent blocking and wake up for CPU is a very heavy burden, is bound to bring very large pressure to the concurrent performance of the operating system. So it takes a loop to wait, which is called spin lock, and this method is also used at the bottom of AQS lock.
So how does a thread that has not acquired the lock resource loop to wait? Continuous loops consume CPU performance, and this type of spin lock, of course, has a stop condition, which falls into two categories.
- in
Java 1.6
Before, you set the number of spins, and if you go over the number of spins, the cycle will stop, and normally you set the number of spins to 10, and you can set thatHotSpot parameters - XX: PreBlockSpin
Before modifying this parameter, you need to set the parameter first-XX:+UseSpining
Turn on the spin lock. - in
Java 1.6
Later, adaptive spin lock is introduced, which is more intelligent. In this way, the time of lock selection is determined according to the previous time and the state of the lock, rather than the fixed number of spins.
4.2.3 Spin Lock Lock release
When the thread that has not acquired the lock resource fails to acquire the spin lock, the lock will be upgraded to a heavyweight lock and the value in the lock object header Markword will be modified. The modified content is roughly the pointer to the heavyweight lock and the lock flag bit will be changed to 10. The thread is blocked.
When the exit synchronization code block that holds the lock, CAS will compare the Markword content stored in the stack with the current lock object Markword and then set the value. Because the current Markword content has changed, it will definitely fail to set the value. At this time, the thread will release the lock, release the monitor and wake up the waiting thread. Another blocked thread is then woken up to re-compete for the lock resource.
The next chapter talks about heavyweight locks.
Please click on hello to talk about Synchronized? (5)
Brother boy, don’t panic to go! Leave a thumbs-up and comment on the discussion. Welcome to the column face interview don’t panic | Java concurrent programming, a raise don’t have to worry about the interview. Also welcome to pay attention to me, must be a longer better man.