Synchronized is a common interview question that involves a lot of questions and answers, and an experienced interviewer will keep asking questions along with your answers. The following dialog is a series of interview questions.

Interviewer: Talk about synchronized. For a single JVM, synchronized can ensure that only one thread executes a method or a piece of code at the same time in the case of concurrency. It can be used to modify methods or code blocks to achieve concurrent safety control of synchronized code.

Interviewer: You said synchronized can be used to modify methods and blocks of code. What’s the difference? White: Modifiers set the ACC_SYNCHRONIZED identifier in the method access identifier in the underlying implementation, and modifiers block the monitorenter and Monitorexit directives in the underlying implementation.

Interviewer: Can you talk about the underlying implementation principle of the modification method? White: Decompile the bytecode file and you can see that the ACC_SYNCHRONIZED access flag is set in the method flags. Each object is associated with a Monitor, which is locked if and only if the monitor is held by a thread. When a method executes, the thread attempts to acquire the Monitor ownership associated with the object, then executes the method, and finally releases the Monitor ownership when the method completes, either normally or abnormally. During method execution, the thread holds Monitor ownership, and no other thread can acquire monitor ownership associated with the same object.

Be prepared for questions about Java object headers and locks to come up with the above answers.

Interviewer: What about the underlying implementation of the decorator block approach? White: Decompile the bytecode file and you can see that monitorenter is added before the logical code and Monitorexit at the end of the logical code. When the method is executed and the current thread executes the Monitorenter directive in an attempt to acquire ownership of the monitor associated with the object, if the monitor’s counter is 0, the current thread holds the monitor and the monitor counter is set to 1. If the current thread already owns the monitor associated with the object and just wants to regain it, it continues to hold the monitor and increments the monitor counter by 1. If another thread already holds the monitor ownership associated with the object, the current thread blocks until the Monitor counter reaches 0 and tries to acquire ownership again. When the method executes normally or an exception occurs, the Monitorexit directive is executed, releasing monitor ownership and decrement the Monitor counter by one.

Interviewer: You just talked about Monitor. Can you elaborate on that? Xiao Bai: In Java virtual machines, the synchronized synchronized synchronized methods and statements are implemented using Monitor. Each object is associated with a Monitor, and when a thread executes the first instruction in a block of code monitored by a Monitor, that thread must acquire a lock on the referenced object, which is implemented by Monitor. In HotSpot virtual machine, monitor is implemented by ObjectMonitor, which is written in C++. The specific code is in the HotSpot virtual machine source code ObjectMonitor. HPP file.

If you look at the source code, The main properties are count(the number of times the thread acquired the lock), recursions(the number of times the lock reentered), OWNER (pointing to the thread holding the ObjectMonitor object), WaitSet(the set of threads in wait state), and _EntryList(in the lock waiting block state) Thread queue).

When concurrent threads execute synchronized modified methods or statement blocks, they enter EntryList first. When a thread obtains the monitor of the object, the owner variable in the monitor object is set to the current thread, and the counter _count in the monitor object is incremented by 1. The current thread succeeded in obtaining the synchronization lock. Procedure

When a thread in a synchronized modified method or block calls wait(), the current thread releases the monitor object it holds, assigning the owner variable in the monitor object to null, and reducing the count value in the monitor object by 1. The current thread then enters the _WaitSet collection and waits to be woken up.

Interviewer: You mentioned locks in your answer. Where does the lock state of an object exist? White: in the object header of a Java object.

Interviewer: What does the object header contain? Part is the runtime data of the object itself, such as HashCode, GC generation age, lock status flag, lock held by the thread, biased thread ID, biased timestamp, etc., officially called “Mark Word”. One is a type pointer, which is a pointer to the metadata of an object’s class that the virtual machine uses to determine which class the object is an instance of. If the object is a Java array, there must also be a piece of data in the object header to record the length of the array, because the virtual machine can determine the size of the Java object from the metadata information of ordinary Java objects, but not from the array metadata.

Interviewer: What level of lock is synchronized for the lock status identifier in the object header? Xiaobai: Heavyweight lock.

Interviewer: What optimizations did the JVM make for locks? Small white:…

Focus on not getting lost, documenting backend development