Java synchronised mechanism

Scope: static code blocks, methods

It is written as follows:

Object lock = new Object();
synchronised(lock){
	// Business code
}
Copy the code

Multithreading competition for lock is the competition for shared resource lock. Grab the lock object Monintor, modify the lock identifier;

Object memory layout

Biased locking

In lock competition, the probability of the same thread acquiring the lock is high. In order to reduce the cost of acquiring the lock, biased lock is introduced.

When a thread acquires the lock, the thread ID is stored in the object header. When the thread enters and exits the code block later, it does not need to lock and release the lock again;

Bias lock acquisition and revocation

1) Obtain the lock object and judge whether it is in a biased state; (LOCK_1, and threadId is null)

  1. You can bias, through cas, to write the current thread ID to Markword;

    • Write success, lock object upgraded to bias lock
    • Write failure indicates that another thread has acquired the lock and the lock is upgraded to a lightweight lock (this operation needs to wait until the global safe point, i.e. no thread is executing bytecode)
  2. If it is biased, you need to check whether the ThreadID stored in MarkWord is the same as the ThreadID of the current thread

    • If it is equal, the lock is not acquired again and the synchronized code block can be executed directly
    • If not, it indicates that the current lock is biased to other threads. You need to cancel the biased lock and upgrade to a lightweight lock

Lightweight lock

[Fixed] The lightweight lock fails to be set and will be upgraded to lightweight lock.

In contrast to biased locks, lightweight locks point the lock record in the object header to the current thread when the thread creates the lock record.

In other words, the bias lock compares whether the thread ID is the same as the current thread; Lightweight locks compare whether the pointer to the lock object points to itself;

Heavyweight lock

[Fixed] Once a lightweight lock is upgraded to a heavyweight lock, it can only be suspended and blocked waiting to wake up.

The transformation of the lock

Note:

  • 1) The upgrade of locks cannot be reversed
> No lock -> Bias lock -> Lightweight lock -> Heavyweight lock
  • 2) What happens after biased lock CAS fails to replace threadId?
When [the thread holding biased lock reaches the safe point], check the status of the thread holding it [inactive/out of sync code block] release the lock (bias lock mark position is 0) [not out of sync code block] upgrade to lightweight lock (copy the object header markwork to the lock record of the thread holding; Thread lock lock records to hold thread id | sign to 00)
  • 3) Transition from lightweight lock to heavyweight lock?
Pointer [Lock object header Markword lock Record] to [current thread lock record] CAS failed, the number of times is too high. (Upgrade to heavyweight lock, suspend current thread)
    1. Lightweight locks and biased locks both have CAS operations.
Each operation of the lightweight and heavyweight locks copies the markwork in the object header to the current thread lock record. The bias lock directly compares the thread ID of the markwOK lock record, which can be said to reduce the overhead of replication.

User mode and kernel mode

reference

  • Java Synchronised mechanism

  • CPU context switch, user mode, kernel mode