We all know that Java's multi-threaded security is implemented based on the lock mechanism, and the lock performance is often unsatisfactory. The reason is that the two bytecode primitives monitorenter and monitorexit control multi-thread synchronization are implemented by JVM dependent on the operating system mutex. Mutex is a resource-consuming operation that causes the thread to be suspended and needs to be rescheduled back to the original thread in a short period of time.
To optimize the lock mechanism of Java, the concept of lightweight lock was introduced from Java 6.
Lightweight locking is designed to reduce the chance of multiple threads entering mutex, rather than replacing mutex. It uses the CPU primitive compare-and-swap (CAS, assembly command cmpxchg) to try to remedy the problem before entering the mutex.
This article describes in detail how to use CAs to implement lightweight locks.
Detailed Principles
As defined in the Java object model, the object header is a storage area with 2 characters (1 word = 4 byte) length.
The area with the first word length is used to mark synchronization, GC, and hash code.Mark word. The second area points to the class of the object.
In two words, Mark word is the key to implementing lightweight locks. Its structure is shown in the table below.
From the table, we can see that the row with the State being lightweight locked is a lightweight lock tag. The bitfieds name is the pointer to lock record.Lock record is actually a space area allocated to the thread stack..
Before using CAS, copy the mark word on the object. (For more information, see the following section ).
The third item is the heavyweight lock mark. The following State words are very interesting. inflated, which means that the lock has been upgraded to OS-level.
Within the scope of this article, we only need to pay attention to the second and third items.
To intuitively understand the relationship between lock and Mark word, I drew a flowchart:
In the figure, the copy object mark word is mentioned. Because it is out of the original mark word, it is officially prefixed with displaced, that isDisplaced mark word(Replacement markup word ).
This displaced mark word is the key to the implementation of the entire lightweight lock. In cas, compare needs to use it as a condition.
Why copy mark word?
In fact, it is very simple, because it does not want to add synchronization on the underlying operations such as lock and unlock.
After copying the object mark word, JVM makes a step.Exchange pointer operations, That is, the content of the first orange rectangle in the process.
Point the lightweight lock pointer in the object mark word to the stack pointer of the lock record to let other threads know that the object monitor is occupied.
The owner pointer in lock record points to the object mark word to identify which object is locked during the next running.
Intuitively describes the operation of switching pointer.
In the last unlock step, we found that JVM also uses CAs to verify whether the object mark word is accessed by other threads between holding the lock and releasing the lock.
If other threads attempt to obtain the lock during the lock period, they may be suspended, and the heavyweight lock pointer of Mark word will be modified accordingly.
In this case, after unlock, you need to wake up the suspended thread.
Transferred from: detailed explanation of Java lightweight lock principles (lightweight locking )!