Java bias Lock, lightweight lock, and heavyweight lock synchronized principle

Source: Internet
Author: User
Tags cas

Java Object Header and monitor

Java object headers are the basis for implementing synchronized lock objects, and the lock objects used by synchronized are stored in the Java object header.

The object header contains two parts: Mark Word and Class Metadata Address

Where Mark Word stores the object's hashcode, generational age, lock tag bit, and so on by default the following is the mark Word default storage structure for 32-bit JVMs

Because the object header information is an additional storage cost that is not related to the data defined by the object itself, Mark Word is designed to be a non-fixed data structure to store more valid data, taking into account the space efficiency of the JVM, which will reuse its own storage space based on the state of the object itself, such as a 32-bit JVM , in addition to the mark Word default storage structure listed above, there are the following possible changes to the structure:

Realization of the synchronized of the heavy-class lock

A heavyweight lock is an object lock that is usually said to be synchronized, and the lock identification bit is 10, where the pointer points to the starting address of a monitor object (also known as a pipe or monitor lock). Each object has a monitor associated with it, and the relationship between the object and its monitor is implemented in a variety of ways, such as when Monitor can be created with an object for destruction or automatically generated when a thread attempts to acquire an object lock, but when a monitor is held by a thread, It is in a locked state.

A simple description of the process of acquiring locks by multithreading, when multiple threads access a synchronized code at the same time, first enters the Entry set when the thread acquires the object's monitor, enters the owner area and sets the owner variable in monitor to the current thread. At the same time, the counter in monitor count plus 1, if the thread calls the Wait () method, releases the currently held Monitor,owner variable back to Null,count 1, while the thread enters the Waitset collection waiting to be woken up. If the current thread finishes executing it will also release the Monitor (lock) and reset the value of the variable so that other threads can enter the capture monitor (lock).

As a result, the monitor object exists in the object header of each Java object (pointing to the stored pointer), and the synchronized lock acquires the lock in this way, which is why any object in Java can be used as a lock, and it is also notify/notifyall /wait the reason that the method exists in the top-level object objects.

Spin lock and self-adapting spin

Java threads are mapped to the native thread of the operating system, and if you want to block or wake up a thread, you need the operating system to do it, which requires a transition from a user state to a kernel mindset, so the state transition takes a lot of processor time. For code-simple synchronization blocks (such as Getter () and setter () methods that are synchronized decorated), state transitions can consume more time than user code executes.

The development team of the virtual machine noticed that in many applications, the locked state of the shared data lasted for a short period of time, and it was not worthwhile to suspend and resume the thread for this period of time. If the physical machine has more than one processor, allowing two or more threads to execute concurrently simultaneously, we can let the thread that asks for the lock "wait a moment" but not abandon the processor's execution time and see if the thread holding the lock will release the lock soon. In order for the thread to wait, we just have to let the thread perform a busy loop (spin), which is called a spin lock.

The spin lock is introduced in the JDK1.4.2 and is opened using the-xx:+usespinning. The JDK1.6 has been turned on by default. Spin waits cannot replace blocking. The spin wait itself avoids the overhead of thread switching, but it takes up processor time, so if the lock takes a short time, the spin-wait is very good, and conversely, if the lock takes a long time, the spinning thread will only waste processor resources. Therefore, the time of the spin wait must have a certain limit, if the spin exceeds the limit number of times (the default is 10, you can use-xx:preblockspin to change) did not successfully obtain the lock, you should use the traditional way to hang up the thread.

Adaptive spin locks are introduced into the JDK1.6, which means that the spin time is not fixed. Instead, there are virtual machines that monitor and predict program locks to set the number of spins.

Spin is used in lightweight locks

Lightweight lock

Lightweight lock Boost Program synchronization performance is based on: for most of the lock, the entire synchronization cycle is not competitive (different from the biased lock). This is an empirical data. If there is no competition, lightweight locks use CAS operations to avoid the overhead of using mutexes, but if there is a lock race, there is additional CAS operations in addition to the cost of mutexes, so lightweight locks are slower than traditional heavyweight locks in the event of competition.

Lock process for lightweight locks:
    • When the code enters the synchronization block, if the synchronization object lock state is unlocked (the lock flag bit is "01" state, whether it is biased to "0"), the virtual machine will first establish a space named lock record in the stack frame of the current thread. A copy of the current mark word used to store the lock object, officially known as displaced Mark Word. The state of the thread stack and the object header



    • The copy of Mark Word in the object header is copied to the lock record;

    • After the copy succeeds, the virtual machine uses the CAS operation to attempt to update the lock object's mark Word to a pointer to the lock record, and to point the owner pointer in the lock record in the thread stack frame to the mark Word of object.
    • If this update succeeds, the thread has a lock on the object, and the object Mark Word's lock flag bit is set to "00", which means that the object is in a lightweight lock state, which is the state of the thread stack and the object header.
    • If this update fails, the virtual machine first checks to see if the object's mark word points to the current thread's stack frame, and if it means that the current thread already has a lock on the object, it can go straight to the synchronization block and proceed. Otherwise, multiple threads compete for a lock, the lightweight lock expands to a heavyweight lock, the status value of the lock flag changes to "ten", and Mark Word stores a pointer to a heavyweight lock (mutex), and the thread that waits for the lock goes into a blocking state.


Biased lock

The biased lock is a lock optimization introduced in JDK6, which aims to eliminate the synchronization primitive of data in the non-competitive situation, and further improve the running performance of the program.

A biased lock will favor the first thread that acquires it, and if the lock is not fetched by another thread during the next execution, the thread holding the biased lock will never need to be synchronized. In most cases, the lock does not only have multi-threaded competition, but is always obtained multiple times by the same thread, in order to allow threads to acquire a lock at a lower cost to introduce a biased lock.

When the lock object is first fetched by the thread, the thread uses the CAS operation to record the thread's ID in the object mark Word, with the bias flag bit 1. In the future, when the thread enters and exits the synchronization block, it does not require CAS operations to lock and unlock, simply test whether the object header's Mark Word stores the ID that points to the current thread. If the test succeeds, the thread has already acquired the lock.

When there is another thread trying to acquire the lock, the bias mode is declared to be over. Resumes to an unlocked or lightweight lock state, depending on whether the lock object is currently locked.

The lock is biased, lightweight and heavyweight locks are locked, lightweight locks are optimistic, and heavyweight locks are pessimistic.
When an object is first instantiated, there is no thread to access it. It is biased, meaning that it now thinks that there is only one thread that can access it, so when the first
When the thread accesses it, it will bias to the threads, at which point the object holds a biased lock. In favor of the first thread, this thread uses the CAS operation when modifying the object header to be a biased lock, and
The ThreadID in the object header is changed to its own ID, and then when the object is accessed again, it is only necessary to compare the ID and no more CAs are required to operate.
Once a second thread accesses this object because the biased lock is not actively freed, the second thread can see the object's bias state, indicating that there is already a competition on the object, checking that the thread that originally held the object's lock is still alive, and if it is, you can change the object to a lock-free state. Then re-biased to the new thread, if the original thread is still alive, then immediately execute the operation stack of that thread, check the use of the object, if you still need to hold a bias lock, the bias lock is promoted to a lightweight lock, ( The bias Lock is the time to upgrade to a lightweight lock.)。 If it does not exist, you can revert the object to a lock-free State and then tilt again.
Lightweight locks believe that competition exists, but the level of competition is very light, generally two threads for the same lock operation will be staggered, or a little wait (spin), the other thread will release the lock. But when the spin exceeds a certain number of times, or a thread holds a lock, a spin, and a third visit, the lightweight lock expands to a heavyweight lock, and the heavyweight lock blocks the thread except the thread that owns the lock, preventing the CPU from idling.

Java bias Lock, lightweight lock, and heavyweight lock synchronized principle

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.