A rough summary of the Java lock mechanism

Notes on the Java lock mechanism that you must know about [multithreaded] monthly salary of 20K

1. What is a lock?

In a concurrent environment, multiple threads will compete for the same resource, which may cause data inconsistency. In order to solve this problem, many programming languages ​​have introduced a lock mechanism. Through an abstract lock, to lock the resource.

1.1 How is the Java lock mechanism designed?

In Java, each Object, that is, each object has a lock, which is stored in the object header, and the lock records which thread the current object is occupied.

2. Object, object header, structure

The object includes three parts:: It
对象头stores some runtime information of the object itself, including the following two parts:
1. Mark Word: stores a lot of data related to the current object runtime state
2. ClassPointer: pointer, points to the method of the current object type Type data in the area
实例数据: the content of the attributes and state set when the object is initialized
对齐填充字节: in order to satisfy "the size of the Java object must be a multiple of 8bit"
Insert picture description here

2.1 Mark Word

It is designed to be extremely small, only 32bit, and unstructured, so that under different lock flags, different fields can reuse different bits, so space can be saved.
The lock is stored in Mark Word
Insert picture description here

3. Synchronized

After Synchronized is compiled, it will generate two bytecode instructions, monitorenter and monitorexit, which rely on these two bytecode instructions for thread synchronization

3.1 Synchronized synchronization mechanism

As shown
Insert picture description here

3.2 Why does the Synchronized synchronization mechanism have performance problems?

Because Synchronized is actually compiled with two bytecode instructions, monitorenter and monitorexit, and Monitor is implemented by relying on the mutex lock of the operating system.

Java thread is actually a mapping of operating system threads, so whenever a thread is suspended or awakened, the kernel state of the operating system must be switched. This operation is relatively heavyweightIn some cases, even the switching time itself will exceed the thread execution time. In this case, using Synchronized will have a serious impact on the performance of the program.
Starting from Java6, Synchronized has been optimized, introducing biased locks and lightweight locks

4. No lock, deflection lock, lightweight lock, heavyweight lock

4.1 No lock

As the name implies, the resource is not locked, and all threads can access the same resource, which may cause two situations

  1. An object will not appear in a multi-threaded environment, or even if it appears in a multi-threaded environment, there will be no competition, then there is really no need to protect this object, just let him call each thread
  2. Resources will be competed, but I don’t want to lock resources, but I still want to control multiple threads through some mechanism, for example, if multiple threads want to modify the same value, weNot by locking resources, but by other means. At the same time, only one thread can be modified successfully, and other threads that fail to modify will continue to try until the modification is successful. This is CAS (Compare and Swap). CAS is implemented by one instruction in the operating system, so it can guarantee atomicity.
    Insert picture description here

In most cases, the efficiency of lock-free programming is very high, but this does not mean that lock-free can fully replace locked

4.2 Bias lock

If an object is locked, but only one thread will acquire the object lock in actual operation, the most ideal way is not to switch the thread state, nor to acquire the lock through CAS, because it will cost more or less Resources

What we envision is that it is best for the object to recognize this thread. As long as this thread comes, the object will directly hand over the lock. We can think that the lock prefers this thread, so it is called a biased lock.

Find the third-to-last bit by the lock flag being 01. If it is 1, it means that it is a biased lock. Then look at the first 23 bits to determine whether the current thread ID is a regular customer.
Insert picture description here
If it is found that there is not only one thread at present, but multiple threads are competing for the lock, then the biased lock will be upgraded to a lightweight lock

4.3 Lightweight lock

Instead of finding the thread that holds the lock according to the thread ID like a biased lock, it looks at the pointer to the lock record in the stack for the first 30 bits.

When a thread wants to acquire a lock on an object, if it sees the lock flag bit 00, then it knows that it is a lightweight lock.
At this time, the thread will open up a space called Lock Record in its own private virtual machine stack.
What is stored in LockRecord is a copy of Mark Word in the object header and the owner pointer.

4.3.1 The binding process of lightweight locks and threads

The thread tries to acquire the lock through CAS. Once acquired, it will copy the Mark Word in the object header to the Lock Record, and point the owner pointer in the Lock Record to the object.

On the other hand, the first 30 bits of the Mark Word of the object will generate a pointer to the Lock Record in the thread virtual machine stack.
Insert picture description here

4.3.2 After the lightweight lock is locked, what should other threads do if they want to acquire it?

Other threads will spin and wait

Spin
can be understood as a kind of polling. The thread itself is constantly looping, trying to see if the lock of the target object is released, if it is released, it will be acquired, if not, it will go to the next loop.

This method is different from being suspended by the operating system becauseIf the lock of the object will be released soon, spin does not need to perform system interruption and on-site recovery, so it is more efficient.

Spin is equivalent to the CPU idling. If it spins for a long time, it will waste CPU resources, so an optimization called "adaptive spinning" appears.

Adaptive spin.
Simply put,The spin time is no longer fixed, but is determined by the last spin time on the same lock and the lock state.
For example, for this lock, the thread that is currently spinning waiting has just successfully acquired the lock, but the lock is currently occupied by other threads, then the virtual machine will think that this spin is also likely to succeed. In turn, it will allow longer spin times.

If the number of threads waiting for spin exceeds half of the number of CPU cores, or the number of spins exceeds 10 times, it will be upgraded to a heavyweight lock

4.4 Heavyweight lock

If it is marked as a heavyweight lock, then just like the original, the thread needs to be controlled by the Monitor. At this time, the resource will be completely locked, and the control of the thread is the most stringent

Guess you like

Origin blog.csdn.net/weixin_41541562/article/details/108622336