Daily sentence

It is the starry firmament of heaven and the moral law within me that fills the soul. – Kant

Biased locking

In most cases, there is no multi-thread competition for locks, and locks are always acquired by the same thread many times. In order to make the cost of locking lower, biased locks are introduced. When a thread accesses a block and acquires a Lock, the thread ID of Bias Lock is stored in the Lock Record in the object header and stack frame. Later, the thread does not need to spend CAS to Lock and unlock the block when it enters and exits the block. A simple test is to see if the Mark Word in the object header stores a bias lock to the current thread

If the test succeeds, the thread has acquired the lock.

If the test fails, it is necessary to test whether the Mark of biased lock in Mark Word is set to 1 (indicating that it is currently biased lock). If not, CAS competitive lock (lightweight lock) is used. If so, try to point the biased lock of the object header to the current thread using a CAS operation (reinitialize the biased lock pair for the current thread, and execute the resource).


Bias lock revocation

Biased locks use a mechanism that waits until a race occurs to release the lock, so the thread holding the biased lock will release the lock only when other threads attempt to contest the biased lock.

Biased locking revocation, needs to wait for the global security point (at this point in time not execute bytecode), it will first suspend threads with biased locking, and then check whether hold biased locking thread alive, if the thread is not active, head of state is set to do not have a lock will object, if the thread is still alive, stack with biased locking may be implemented, The lock records in the stack and the Mark Word of the object header are either rebiased to other threads, or reverted to lockless or marked that the object is not suitable as a biased lock, finally waking up the suspended thread.

Lightweight lock

Lightweight lock and lock: Before a thread executes a synchronized block, the JVM creates a space in the current thread’s frame to store the lock record and copies the Mark Word from the object header into the lock record.

The product is officially called the taliban Mark Word. The thread then tries to use CAS to replace the Mark Word in the object header with a pointer to the lock record. If it succeeds, the current thread acquires the lock; if it fails, other threads compete for the lock and the current thread attempts to acquire the lock using spin. If there are more than two threads competing for the same lock, the lightweight lock is no longer valid, and the status of the lock flag changes to “10”. The Mark Word stores Pointers to the heavyweight (mutex).

Lightweight lock Unlock: The lightweight unlock will use atomic CAS operation to replace the product Mark Word back to the object head. If successful, no competition will occur. If it fails, it indicates that the current lock is competing, and the lock expands to a heavyweight lock.

Heavyweight lock

Heavyweight locking is the most basic implementation of locking in Java virtual machines. In this state, the Java virtual machine blocks the threads that failed to lock and wakes them up when the target lock is released.

Here is my personal understanding:

Biased locks, lightweight locks are optimistic locks, heavyweight locks are pessimistic locks.

When an object is first instantiated and no threads are accessing it. It’s biased, meaning it now thinks that only one thread can access it, so when the first thread accesses it, it favors that thread, and in that case, the object holds the biased lock.

  • 0. Bias to the first thread. This thread uses CAS when it changes the object header to bias lock and changes the ThreadID in the object header to its OWN ID. (Set the initialization bias lock record header + bias lock record data)
  • 1. Once a second thread to access the object, because of the biased locking does not take the initiative to release, so the second thread can see objects to state, at this time that already there is competition on the object, check whether the original owners of the thread lock the object is still alive, if you hang up and the object can be become unlocked state, then back to the new thread. (Lock conflict and check original bias lock no longer alive, thread dies directly reset bias lock).
  • 2. If the original thread is still alive, immediately execute the stack of that thread, check the usage of the object, if you still need to hold biased Lock (check the Lock Record of the object header), then biased Lock is upgraded to lightweight Lock, (biased Lock is upgraded to lightweight Lock at this time). (Lock conflicts occur and the lock flags of other objects corresponding to the check thread stack still exist, even if the original bias lock thread survives.)
  • 3. If the object is no longer in use, you can restore it to the unlocked state and re-bias it. (Reorientation)
  • 4. Lightweight locks think that there is competition, but the degree of competition is very light. Generally, two threads will stagger the operation of the same lock, or wait a little (spin), the other thread will release the lock. But when the spin exceeds a certain number, or when one thread is holding the lock, one is spinning, and a third person is calling, the lightweight lock bulges into a heavyweight lock, which blocks all threads except the one that owns the lock, preventing the CPU from idling. (Lightweight lock’s spin (adaptive spin) + upgrade to heavyweight lock (2 + collisions/adaptive spin/long spin)).