There is no such thing as perfect programming, but we shouldn’t be discouraged because programming is a constant pursuit of perfection.



Then analyze it in detail:

First of all, in the case of single thread, no other thread can grab the lock from the current thread, so the current thread can easily grab the lock through CAS. In this case, the location of the lock information in the object header will record the status as the thread Id of the current locked thread. Since no other thread needs the lock, the current thread can have the lock all the time without unlocking it. This state that the single thread does not need to unlock the lock is called biased lock. After JDK6, synchronized defaults to biased locking for single threads.

Then, when there are multiple threads, the phenomenon of multiple threads snatches the lock through CAS will occur, so that the biased lock state will change to lightweight lock. When one thread grabs the lock through CAS, the other threads are still spinning to grab the lock through CAS. If the lock cannot be grabbed for a long time, the CPU resource will be consumed and the CPU usage will reach 100%.

The Object Monitor records the number of spins of the CAS when a thread attempts to grab the lock. When a thread fails to grab the lock after spinning a certain number of times, It is suspended and added to the EntryList of the Object Monitor. This avoids wasting CPU resources due to continuous CAS spin. When a thread releases the lock, the thread in the wait queue is removed and added to the CAS spin grab lock queue. This state is called a heavyweight lock.

Of course, if a single thread releases the lock it owns when multiple threads arrive or if multiple threads grab the lock in the first place, then the unlocked state goes into the lightweight lock state, and then into the heavyweight lock state.