Starting with JDK1.6, the JVM has made various optimizations for locks to share data more efficiently between threads and to address the issue of mutually exclusive synchronization. Since lock optimization topic, can lead to a lot of examination site interview questions, such as lock optimization technique, the optimization technology, CAS implementation principle, the details of the CAS ABA problems and how to solve, such as continuous divergence will cause more problems, such as the escape analysis and so on, it can be seen that technical points are associated, need to accumulate and comb.
Interviewer: What lock optimization techniques are implemented by the JVM? White: spin lock, adaptive spin lock, lock coarser, lock elimination, bias lock, lightweight lock.
Interviewer: What about spin locks? Why spin locks? A spin lock is a busy loop that allows the current thread to wait for the lock to be released and then acquire the lock without giving up the processor’s execution time. Spin locks were introduced to save the overhead of thread suspension and recovery.
Interviewer: You just said that the introduction of spin locks saves the overhead of thread suspension and recovery, but loops also require processor time. How do you control the number of spins? The default is 10 spins, which can also be configured using the JVM parameter -xx :PreBlockSpin. Of course, these spins are fixed, so adaptive spin locks are introduced. The number of spins on the same lock is determined by the previous number of spins on the lock and the state of the lock owner. If the previous thread successfully acquired the lock and ran normally, then the possibility of acquiring the lock this time is very high, so the number of spins is relatively more; If the previous thread rarely succeeded in acquiring the lock, then the probability of acquiring the lock this time is also very low, and the spin may not be performed.
Interviewer: What does lock coarsening optimize? Xiao Bai: If the same thread repeatedly obtains and releases the lock of the same object in a code, it will produce unnecessary performance overhead. Therefore, it is necessary to expand the scope of acquiring the lock of the same object only once, obtaining the lock in the head and releasing the lock in the tail.
Interviewer: What is lock elimination? Xiao Bai: Lock elimination refers to the JIT at runtime analysis of the use of lock synchronization code in the actual run time can not exist shared data contention, to remove the lock. For example, if a local variable inside a method cannot be referenced externally, then it does not need to be locked and can be unlocked. (Note: If escape analysis is mentioned in your answer, the interviewer will probably ask you what escape analysis is, so be prepared.)
Interviewer: Tell me more about bias locking? Bias lock means that if a thread holds a lock, the thread holding bias lock will no longer need to synchronize as long as the lock is not held by other threads in the subsequent process. Information about this bias lock is stored in the object header of the Java object. In the HotSpot VIRTUAL machine, the layout of Java objects stored in memory is divided into three areas: object headers, instance data, and aligned padding. The object header contains two parts. The first part contains the object’s HashCode, generation age, lock flag bit, lock held by the thread, thread ID and other data. The length of this part of the data is 32bit and 64bit respectively in 32-bit and 64-bit VMS, which is officially called Mark World. The following figure shows what is stored in the object header in different states:
A normal Java object is initially unlocked, and the data stored in Mark World is shown in the first line above. When a partial lock is enabled on the vm and the lock object is first acquired by the thread, the lock ID is set to 01 and the thread ID is set to Mark World using CAS. If the CAS operation succeeds, the thread can continue to execute the relevant synchronization code. If another thread attempts to acquire the lock at this time, there are two situations. One is that the lock object is not locked, and the partial lock is revoked and the lock state is restored. If the object is locked, then partial lock failure and upgrade to lightweight lock will create a lock record space in the current thread’s stack frame. This space will store a copy of the Mark World in the object header, that is, copy a copy to this lock record space. At the same time, the virtual machine uses CAS to try to update the pointer of the lock record space to Mark World. If THE CAS operation succeeds, the current thread acquires the lock, which is in the lightweight lock state with the lock flag at 00.
Interviewer: You just mentioned that virtual machines use CAS for update operations. What is CAS in Java and how is it implemented? Xiao Bai: CAS (Compare and swap) is a common technology to achieve concurrent security through hardware. At the bottom layer, the CAS instruction of CPU is used to lock the cache or the bus to achieve atomic operations between multiple processors. This is implemented by having three operands, the memory value V, the old expected value E, and the new value U to be modified. The memory value V will be changed to U only if and only if the expected value E and the memory value V are the same, otherwise nothing will be done. The underlying implementation of CAS uses C++, in which the corresponding calling code is selected according to the different operating system and processor. Take Windows and x86 processors as an example. If there are multiple processors, the atomic operation between multiple processors is realized by locking the cache or bus with the CMPXCHG instruction prefixed with lock. In the case of a uniprocessor, atomic operations are performed using CMPXCHG instructions.
Interviewer: Do you know the ABA problem in CAS? Small white: Know the CAS is if and only if the old phase at the same time, the expected value and memory value E V to amend the memory value V to U, if memory V does not change is updated, the possible memory value turns out to be A, but the middle is to B, then changed to A, when using the CAS check again found no change at this time, but in fact changed, That’s the ABA problem.
Interviewer: How can this problem be solved? Bai: An AtomicStampedReference in Java will solve the ABA problem. An internal implementation adds a stamp attribute similar to the version number, which is automatically updated. The implementation first checks whether the current reference is equal to the expected reference and whether the current stamp is equal to the expected stamp. If they are all equal, the values of the reference and the stamp are set to the given updated value in atomic mode.
Focus on not getting lost, documenting backend development