How to implement the synchronized lock expansion mechanism in Java
synchronized
In JDK 1.5, synchronized needs to call the monitor lock (Monitor) to implement, and the monitor lock essentially depends on the underlying layer. It is implemented by the operating system's Mutex Lock (mutex lock). When releasing and acquiring the mutex lock, it needs to be converted from user mode to kernel mode, which causes high costs and requires a long execution time. This kind of lock that relies on the operating system's Mutex Lock implementation is called a "heavyweight lock".
What are user mode and kernel mode?
User Mode: When the process is executing the user's own code, it is said to be in the user running state. Kernel Mode: When a task (process) executes a system call and is trapped in the kernel code, we say that the process is in the kernel running state. At this time, the processor is executing in the kernel code with the highest privilege level.
Why are we divided into kernel mode and user mode?
Assuming that there is no distinction between kernel mode and user mode, the program can read and write hardware resources at will, such as reading, writing and allocating memory at will. In this way, if the programmer accidentally writes inappropriate content to where it should not be Where written, it is likely to cause the system to crash.
With the distinction between user mode and kernel mode, the program will perform a series of verifications and inspections when performing an operation. Only after confirming that there is no problem can it operate the resources normally, so that it will not Worry about accidentally damaging the system, that is, The distinction between kernel mode and user mode can make the program run more safely, but at the same time, switching between the two modes will cause a certain performance overhead.
Lock expansion
In JDK 1.6, in order to solve the performance consumption caused by acquiring and releasing locks, the states of "biased lock" and "lightweight lock" were introduced , at this time, there are a total of 4 synchronized states:
No lock
Biased lock
Lightweight lock
Heavyweight lock
The level of the lock is upgraded in the order mentioned above. Let’s upgrade this The process is called "lock expansion".
PS: So far, the lock upgrade is one-way, that is to say, it can only be upgraded from low to high (no lock-> ; Bias lock-> lightweight lock-> heavyweight lock), there will be no lock degradation.
Why can lock expansion optimize the performance of synchronized? When we understand these lock states, we will naturally have the answer. Let's take a look at it together.
Biased lock
HotSpot The author found through research and practice that in most cases, there is no multi-thread competition for locks, and they are always acquired multiple times by the same thread. In order to allow threads to obtain the lock The cost was lower, so bias locks were introduced.
Biased Locking means that it will be biased towards the first thread to access the lock. If only one thread accesses the synchronization lock during operation, there will be no multi-thread contention. Then the thread does not need to trigger synchronization. In this case, a bias lock will be added to the thread.
Biased lock execution process
When a thread accesses the synchronized code block and acquires the lock, the thread ID of the lock bias will be stored in the Mark Word of the object header, and the thread ID will be stored in the Mark Word of the object header when the thread enters and exits the synchronized block. Instead of locking and unlocking through CAS operations, it detects whether the bias lock pointing to the current thread is stored in Mark Word. If the thread ID in Mark Word is consistent with the accessed thread ID, you can directly enter the synchronization block to code. Execution, if the thread IDs are different, use CAS to try to acquire the lock. If the acquisition is successful, enter the synchronized block to execute the code. Otherwise, the lock status will be upgraded to a lightweight lock.
Advantages of biased locks
Biased locks are designed to minimize unnecessary lock switching without multi-thread competition, because the acquisition and release of locks rely on multiple times. CAS atomic instruction, and biased lock only needs to execute the CAS atomic instruction once when replacing the thread ID.
Mark Word Extended Knowledge: Memory Layout
In the HotSpot virtual machine, the layout of objects stored in memory can be divided into the following 3 areas:
Object Header
Instance Data
Alignment Filling(Padding)
The object header also contains:
Mark Word (mark field): Our bias lock information is stored in this area.
Klass Pointer (Class object pointer)
The layout of the object in memory is as follows:
In JDK 1.6, biased locking is enabled by default. You can disable biased locking through the "-XX:-UseBiasedLocking=false" command.
Lightweight lock
The purpose of introducing lightweight lock is to reduce the use of traditional heavyweight locks in the operating system Mutex Lock (mutex lock) without multi-thread competition. The performance consumption caused by locks. If you use Mutex Lock, each operation of acquiring and releasing a lock will cause switching between user mode and kernel mode, which will cause a huge performance overhead for the system.
When the bias lock is turned off or multiple threads compete for the bias lock, the bias lock will be upgraded to a lightweight lock. The acquisition and release of the lightweight lock are completed through CAS, and the lock acquisition may be through A certain number of spins to complete.
Notes
It needs to be emphasized: Lightweight locks are not used to replace heavyweight locks. Their original intention is to use them without multi-thread competition. , Reduce the performance consumption caused by the use of traditional heavyweight locks. The scenario that lightweight locks adapt to is the situation where threads alternately execute synchronized blocks. If multiple threads access it at the same time, the lightweight lock will expand into a heavyweight lock.
Heavyweight lock
synchronized relies on the monitor to implement method synchronization or code block synchronization. Code block synchronization is implemented using the monitorenter and monitorexit instructions. The monitorenter instruction is compiled after Inserted at the beginning of the synchronized code block, while monitorexit is inserted at the end of the method and the exception. Any object has a Monitor associated with it. When a Monitor is held, it will be in a locked state.
The locking code is as follows:
public class SynchronizedToMonitorExample { public static void main(String[] args) { int count = 0; synchronized (SynchronizedToMonitorExample.class) { for (int i = 0; i < 10; i++) { count++; } } System.out.println(count); } }
When we compile the above code into bytecode, its content is as follows:
It can be seen from the above results that there are multiple monitorenter and monitorexit instructions in the execution of the main method. It can be seen that synchronized is implemented by relying on the Monitor monitor lock, and The monitor lock relies on the operating system's mutex lock (Mutex Lock). Each time the mutex lock is acquired and released, it will switch between user mode and kernel mode, which increases the performance overhead of the system.
The above is the detailed content of How to implement the synchronized lock expansion mechanism in Java. For more information, please follow other related articles on the PHP Chinese website!

The class loader ensures the consistency and compatibility of Java programs on different platforms through unified class file format, dynamic loading, parent delegation model and platform-independent bytecode, and achieves platform independence.

The code generated by the Java compiler is platform-independent, but the code that is ultimately executed is platform-specific. 1. Java source code is compiled into platform-independent bytecode. 2. The JVM converts bytecode into machine code for a specific platform, ensuring cross-platform operation but performance may be different.

Multithreading is important in modern programming because it can improve program responsiveness and resource utilization and handle complex concurrent tasks. JVM ensures the consistency and efficiency of multithreads on different operating systems through thread mapping, scheduling mechanism and synchronization lock mechanism.

Java's platform independence means that the code written can run on any platform with JVM installed without modification. 1) Java source code is compiled into bytecode, 2) Bytecode is interpreted and executed by the JVM, 3) The JVM provides memory management and garbage collection functions to ensure that the program runs on different operating systems.

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

Cloud computing significantly improves Java's platform independence. 1) Java code is compiled into bytecode and executed by the JVM on different operating systems to ensure cross-platform operation. 2) Use Docker and Kubernetes to deploy Java applications to improve portability and scalability.

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

Containerization technologies such as Docker enhance rather than replace Java's platform independence. 1) Ensure consistency across environments, 2) Manage dependencies, including specific JVM versions, 3) Simplify the deployment process to make Java applications more adaptable and manageable.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

MantisBT
Mantis is an easy-to-deploy web-based defect tracking tool designed to aid in product defect tracking. It requires PHP, MySQL and a web server. Check out our demo and hosting services.

SublimeText3 Chinese version
Chinese version, very easy to use

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),