当前位置:网站首页>30 minutes to thoroughly understand the synchronized lock upgrade process
30 minutes to thoroughly understand the synchronized lock upgrade process
2022-07-26 10:04:00 【Java confidant_】
Click on the official account , Practical technical articles Know in time 
stay Java In the field of concurrent programming , We will use the lock during the meeting , For example, in the multi-threaded environment, in order to prevent some thread safety problems , There may be some unexpected problems , So I've sorted out a series about JDK The problem of middle lock , Help you understand them more deeply .
synchronized It's really a heavyweight lock ?
I believe most people have encountered this problem during the interview , The answer is No . This depends on JDK To judge . If JDK The version of is in 1.5 Before using synchronized The principle of lock is as follows :
Add one before and after the resources that need to be locked “
monitorenter” and “monitorexit” Instructions .When a thread needs to enter this code critical area , Get involved first “ Grab the lock ”( The essence is to get monitor Authority )
If lock grabbing fails , Will be blocked , At this point, control can only be handed over to the operating system , It will start from
user modeSwitch tokernel mode, The operating system is responsible for the scheduling between threads and the state change of threads , You need to switch between these two modes frequently ( Context conversion ).
It can be seen that , Under the condition of the old mode, the cost of obtaining locks is relatively large , So later JDK The author of JDK Designed in Lock Interface , use CAS To implement the lock , To improve performance .
But when the competition is very fierce , use CAS The way may not get the lock all the time , No matter how much CAS It's also a waste CPU, The performance loss in this state will be higher than synchronized higher . So in this case , It's better to upgrade and lock directly , Let the operating system intervene .
Because of this , Therefore, there will be the saying of lock upgrade later .
synchronized Lock upgrade
Biased locking
stay synchronized In the process of upgrading , The first step will be upgraded to bias lock . The so-called deflection lock , Its essence is to let the lock remember the requested thread .
In most scenarios , In fact, there are more single thread access locks ,JDK The author of is reconstructing synchronized When , Designed a for the object header bit position , Specifically used to record lock information , Specifically, we can understand it through the following actual case :
public static void main(String[] args) throws InterruptedException {
Object o = new Object();
System.out.println(" The synchronization block has not been entered ");
System.out.println("markword:" + ClassLayout.parseInstance(o).toPrintable());
// Default JVM There will be a warm-up phase during startup , Therefore, the deflection lock will not be opened by default
Thread.sleep(5000);
Object b = new Object();
System.out.println(" The synchronization block has not been entered ");
System.out.println("markword:" + ClassLayout.parseInstance(b).toPrintable());
synchronized (o){
System.out.println(" Entering the synchronization block ");
System.out.println("markword:" + ClassLayout.parseInstance(o).toPrintable());
}
}Pay attention to introducing some third-party dependencies , Help us view the information of the object header :
<dependency>
<groupId>org.openjdk.jol</groupId>
<artifactId>jol-core</artifactId>
// This version number is different , The format of the viewed content is also different
<version>0.16</version>
</dependency>The console output is as follows :
The synchronization block has not been entered
# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
markword:java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
The synchronization block has not been entered
markword:java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Entering the synchronization block
markword:java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x00007000050ee988 (thin lock: 0x00007000050ee988)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total In this case , If you carefully observe the contents of the console , You can find , When JVM When it started , The lock flag bit of the object head is unlocked . But after a whole child ( Probably 4 Seconds later ), It will become a biasable The state of . If you need to adjust the delay time , You can use the parameter -XX:BiasedLockingStartupDelay=0 To control .
Here I'll explain biasable The meaning of :
biasable yes JVM Help us set the status , In this state , Once a thread accesses the lock , It's going to be direct CAS Modify the thread in the object header id. If it works , Then directly upgrade to bias lock . Otherwise, it will enter the next state of the lock -- Lightweight lock .
ps:JVM Because during the warm-up phase , There are many steps to use synchronized, So before just starting 4 In the second , Will not directly synchronized The mark of the lock is upgraded to biasable state . This is to reduce some unnecessary performance losses .
Lightweight lock
When a lock is accessed by a thread , It will become a biased lock state , When the new thread accesses the lock again , Will there be any change in the lock ?
Here I have sorted out a flow chart of lock changes , As shown below :
To verify this process , We can practice through the following case :
public static void main(String[] args) throws InterruptedException {
// sleep 5s
Thread.sleep(5000);
Object o = new Object();
System.out.println(" Synchronization block not entered ,MarkWord by :");
System.out.println(ClassLayout.parseInstance(o).toPrintable());
synchronized (o){
System.out.println((" Go into sync block ,MarkWord by :"));
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
Thread t2 = new Thread(() -> {
synchronized (o) {
System.out.println(" The new thread acquires the lock ,MarkWord by :");
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
});
t2.start();
t2.join();
System.out.println(" The main thread looks at the lock object again ,MarkWord by :");
System.out.println(ClassLayout.parseInstance(o).toPrintable());
synchronized (o){
System.out.println((" The main thread enters the synchronization block again ,MarkWord by :"));
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
synchronized (b) {
System.out.println((" The main thread enters the synchronization block again , And call hashcode Method ,MarkWord by :"));
b.hashCode();
System.out.println(ClassLayout.parseInstance(b).toPrintable());
}
}Then let's observe the results of the implementation :
/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63267,suspend=y,server=n -javaagent:/Users/linhao/Library/Caches/IntelliJIdea2019.3/captureAgent/debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_181.jdk/Contents/Home/lib/tools.jar:/Users/linhao/IdeaProjects/my-github/concurrence-programming-lession/target/classes:/Users/linhao/.m2/repository/org/junit/jupiter/junit-jupiter/5.9.0-RC1/junit-jupiter-5.9.0-RC1.jar:/Users/linhao/.m2/repository/org/junit/jupiter/junit-jupiter-api/5.5.2/junit-jupiter-api-5.5.2.jar:/Users/linhao/.m2/repository/org/apiguardian/apiguardian-api/1.1.0/apiguardian-api-1.1.0.jar:/Users/linhao/.m2/repository/org/opentest4j/opentest4j/1.2.0/opentest4j-1.2.0.jar:/Users/linhao/.m2/repository/org/junit/platform/junit-platform-commons/1.5.2/junit-platform-commons-1.5.2.jar:/Users/linhao/.m2/repository/org/junit/jupiter/junit-jupiter-params/5.5.2/junit-jupiter-params-5.5.2.jar:/Users/linhao/.m2/repository/org/junit/jupiter/junit-jupiter-engine/5.5.2/junit-jupiter-engine-5.5.2.jar:/Users/linhao/.m2/repository/org/junit/platform/junit-platform-engine/1.5.2/junit-platform-engine-1.5.2.jar:/Users/linhao/.m2/repository/org/openjdk/jol/jol-core/0.16/jol-core-0.16.jar:/Users/linhao/.m2/repository/org/apache/dubbo/dubbo/2.7.8/dubbo-2.7.8.jar:/Users/linhao/.m2/repository/org/springframework/spring-context/5.2.5.RELEASE/spring-context-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/spring-aop/5.2.5.RELEASE/spring-aop-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/spring-beans/5.2.5.RELEASE/spring-beans-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/spring-expression/5.2.5.RELEASE/spring-expression-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/com/alibaba/spring/spring-context-support/1.0.8/spring-context-support-1.0.8.jar:/Users/linhao/.m2/repository/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar:/Users/linhao/.m2/repository/io/netty/netty-all/4.1.48.Final/netty-all-4.1.48.Final.jar:/Users/linhao/.m2/repository/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar:/Users/linhao/.m2/repository/org/yaml/snakeyaml/1.25/snakeyaml-1.25.jar:/Users/linhao/.m2/repository/com/alibaba/fastjson/1.2.70/fastjson-1.2.70.jar:/Users/linhao/.m2/repository/org/apache/zookeeper/zookeeper/3.5.3-beta/zookeeper-3.5.3-beta.jar:/Users/linhao/.m2/repository/commons-cli/commons-cli/1.2/commons-cli-1.2.jar:/Users/linhao/.m2/repository/io/netty/netty/3.10.5.Final/netty-3.10.5.Final.jar:/Users/linhao/.m2/repository/org/apache/dubbo/dubbo-spring-boot-starter/2.7.8/dubbo-spring-boot-starter-2.7.8.jar:/Users/linhao/.m2/repository/org/apache/dubbo/dubbo-spring-boot-autoconfigure/2.7.8/dubbo-spring-boot-autoconfigure-2.7.8.jar:/Users/linhao/.m2/repository/org/apache/dubbo/dubbo-spring-boot-autoconfigure-compatible/2.7.8/dubbo-spring-boot-autoconfigure-compatible-2.7.8.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter/2.2.6.RELEASE/spring-boot-starter-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot/2.2.6.RELEASE/spring-boot-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/2.2.6.RELEASE/spring-boot-autoconfigure-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter-logging/2.2.6.RELEASE/spring-boot-starter-logging-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/linhao/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar:/Users/linhao/.m2/repository/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar:/Users/linhao/.m2/repository/org/apache/logging/log4j/log4j-to-slf4j/2.12.1/log4j-to-slf4j-2.12.1.jar:/Users/linhao/.m2/repository/org/apache/logging/log4j/log4j-api/2.12.1/log4j-api-2.12.1.jar:/Users/linhao/.m2/repository/org/slf4j/jul-to-slf4j/1.7.30/jul-to-slf4j-1.7.30.jar:/Users/linhao/.m2/repository/jakarta/annotation/jakarta.annotation-api/1.3.5/jakarta.annotation-api-1.3.5.jar:/Users/linhao/.m2/repository/org/springframework/spring-core/5.2.5.RELEASE/spring-core-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/spring-jcl/5.2.5.RELEASE/spring-jcl-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter-web/2.2.6.RELEASE/spring-boot-starter-web-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter-json/2.2.6.RELEASE/spring-boot-starter-json-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.10.3/jackson-databind-2.10.3.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.10.3/jackson-annotations-2.10.3.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.10.3/jackson-core-2.10.3.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.10.3/jackson-datatype-jdk8-2.10.3.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.10.3/jackson-datatype-jsr310-2.10.3.jar:/Users/linhao/.m2/repository/com/fasterxml/jackson/module/jackson-module-parameter-names/2.10.3/jackson-module-parameter-names-2.10.3.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter-validation/2.2.6.RELEASE/spring-boot-starter-validation-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/jakarta/validation/jakarta.validation-api/2.0.2/jakarta.validation-api-2.0.2.jar:/Users/linhao/.m2/repository/org/hibernate/validator/hibernate-validator/6.0.18.Final/hibernate-validator-6.0.18.Final.jar:/Users/linhao/.m2/repository/org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final.jar:/Users/linhao/.m2/repository/com/fasterxml/classmate/1.5.1/classmate-1.5.1.jar:/Users/linhao/.m2/repository/org/springframework/spring-web/5.2.5.RELEASE/spring-web-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/spring-webmvc/5.2.5.RELEASE/spring-webmvc-5.2.5.RELEASE.jar:/Users/linhao/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/2.2.6.RELEASE/spring-boot-starter-tomcat-2.2.6.RELEASE.jar:/Users/linhao/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.33/tomcat-embed-core-9.0.33.jar:/Users/linhao/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/9.0.33/tomcat-embed-el-9.0.33.jar:/Users/linhao/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/9.0.33/tomcat-embed-websocket-9.0.33.jar:/Users/linhao/.m2/repository/org/apache/curator/curator-framework/2.12.0/curator-framework-2.12.0.jar:/Users/linhao/.m2/repository/org/apache/curator/curator-client/2.12.0/curator-client-2.12.0.jar:/Users/linhao/.m2/repository/com/google/guava/guava/16.0.1/guava-16.0.1.jar:/Users/linhao/.m2/repository/org/apache/curator/curator-recipes/2.12.0/curator-recipes-2.12.0.jar:/Users/linhao/.m2/repository/com/alibaba/transmittable-thread-local/2.12.2/transmittable-thread-local-2.12.2.jar:/Users/linhao/.m2/repository/org/apache/rocketmq/rocketmq-client/4.8.0/rocketmq-client-4.8.0.jar:/Users/linhao/.m2/repository/org/apache/rocketmq/rocketmq-common/4.8.0/rocketmq-common-4.8.0.jar:/Users/linhao/.m2/repository/org/apache/rocketmq/rocketmq-remoting/4.8.0/rocketmq-remoting-4.8.0.jar:/Users/linhao/.m2/repository/org/apache/rocketmq/rocketmq-logging/4.8.0/rocketmq-logging-4.8.0.jar:/Users/linhao/.m2/repository/io/netty/netty-tcnative-boringssl-static/2.0.30.Final/netty-tcnative-boringssl-static-2.0.30.Final.jar:/Users/linhao/.m2/repository/commons-validator/commons-validator/1.6/commons-validator-1.6.jar:/Users/linhao/.m2/repository/commons-beanutils/commons-beanutils/1.9.2/commons-beanutils-1.9.2.jar:/Users/linhao/.m2/repository/commons-digester/commons-digester/1.8.1/commons-digester-1.8.1.jar:/Users/linhao/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/Users/linhao/.m2/repository/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar:/Users/linhao/.m2/repository/org/apache/commons/commons-lang3/3.9/commons-lang3-3.9.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar" Concurrent programming 03. View memory layout information .MarkWordDemo_4
Connected to the target VM, address: '127.0.0.1:63267', transport: 'socket'
# WARNING: Unable to attach Serviceability Agent. You can try again with escalated privileges. Two options: a) use -Djol.tryWithSudo=true to try with sudo; b) echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
Synchronization block not entered ,MarkWord by :java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Synchronization block not entered ,MarkWord by :java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000005 (biasable; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Go into sync block ,MarkWord by :java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x00007fe8a5009805 (biased: 0x0000001ffa294026; epoch: 0; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
The new thread acquires the lock ,MarkWord by :
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x000070000ba03908 (thin lock: 0x000070000ba03908)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
The main thread looks at the lock object again ,MarkWord by :
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000000000000001 (non-biasable; age: 0)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
The main thread enters the synchronization block again ,MarkWord by :
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x0000700009f87980 (thin lock: 0x0000700009f87980)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
The main thread enters the synchronization block again , And call hashcode Method ,MarkWord by :
java.lang.Object object internals:
OFF SZ TYPE DESCRIPTION VALUE
0 8 (object header: mark) 0x00007fe8a51391ea (fat lock: 0x00007fe8a51391ea)
8 4 (object header: class) 0xf80001e5
12 4 (object alignment gap)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
Disconnected from the target VM, address: '127.0.0.1:63267', transport: 'socket'
Process finished with exit code 0Through the print content in the console, we can find , The state of the lock has gone through the following steps :
biasable state
In this state , Lock is a state to be biased , At this time, if there is a thread request . But if it is just started JVM The state of the word , The head of the object will be non-biasable state , Only wait jvm Warm up for a period of time ( It's about 4 second ), Will stay and turn into biasable state .
biased state
When the first request obtains the lock , The lock state will become biased to the lock state , That is to say biased. If you are in the biased lock state , There are also new threads involved in lock grabbing , Then lock escalation will occur , Enter the lightweight lock state stage .
thin lock state
You can see , When a lock has experienced a biased lock state , Later, if another thread accesses it , It will be upgraded to the state of lightweight lock , That is to say thin lock state .
fat lock state
When we call hashcode Method time , Will find , The head of the lock object will have an extra one called fat lock The state of , That means , At this time, the lock has been upgraded to a heavyweight lock .
Heavyweight lock
When a lock is already in the state of lightweight lock , If there are more threads trying to acquire the lock , Then the lock will be accessed by multiple threads in a spinning way , When the number of visits reaches a certain limit ,synchronized It will be automatically upgraded to the state of heavyweight lock .
When upgrading to a heavyweight lock , Lock object's mark word The pointer in no longer points to lock record, It points to the lock object in the heap monitor object . When multiple threads access synchronous code at the same time , These threads will first try to get the corresponding value of the current lock object monitor The ownership of the :
To be successful , Determine whether the current thread is reentrant , If it's reentry, then
recursions+1Acquisition failure , The current thread will be blocked , Waiting for other threads to be awakened after unlocking , Compete for lock objects again
In the case of heavyweight locks , The process of adding and unlocking involves the operation of the operating system Mutex Lock Do mutually exclusive operations , The scheduling between threads and the state change process of threads need to switch between user state and core state , It's going to consume a lot of cpu resources , Resulting in reduced performance .
What are several ways to upgrade a lock to a heavyweight state ?
call wait Method
Call the... Of the object in the synchronized code block hashcode Method
Finally, I drew a flow chart of lock upgrade to share with you :

Summary
Actually JVM Have been to synchronized optimized . It can be used directly , As for the strength of the lock ,JVM The bottom layer is ready. We can use it directly . But as an engineer , Understanding these underlying principles can still increase our internal skills .
recommend
Technical involution group , Learn together !!

PS: Because the official account platform changed the push rules. , If you don't want to miss the content , Remember to click after reading “ Looking at ”, Add one “ Star standard ”, In this way, each new article push will appear in your subscription list for the first time . spot “ Looking at ” Support us !

边栏推荐
- 数通基础-二层交换原理
- 面试突击68:为什么 TCP 需要 3 次握手?
- Draw arrows with openlayer
- 服务器内存故障预测居然可以这样做!
- Alibaba cloud technology expert haochendong: cloud observability - problem discovery and positioning practice
- 论文笔记(SESSION-BASED RECOMMENDATIONS WITHRECURRENT NEURAL NETWORKS)
- In the same CONDA environment, install pytroch first and then tensorflow
- 苹果独占鳌头,三星大举复兴,国产手机在高端市场颗粒无收
- protobuf的基本用法
- 挡不住了,纯国产PC已就位,美国的软硬件体系垄断正式被破
猜你喜欢

Spolicy request case

点赞,《新程序员》电子书限时免费领啦!

Transform between tree and array in JS (hide the children field if the child node of the tree is empty)

Principle analysis and source code interpretation of service discovery

Necessary for beginners: debug breakpoint debugging skills in idea and common breakpoint skills

服务发现原理分析与源码解读

Mqtt x cli officially released: powerful and easy-to-use mqtt 5.0 command line tool
![[fluorescent character effect]](/img/05/4f4c24c787881e073919b63a6864cf.jpg)
[fluorescent character effect]

2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)

Solve proxyerror: CONDA cannot proceed due to an error in your proxy configuration
随机推荐
Azkaban [basic knowledge 01] core concepts + features +web interface + Architecture +job type (you can get started with Azkaban workflow scheduling system in one article)
Server memory failure prediction can actually do this!
Interview shock 68: why does TCP need three handshakes?
2021 windows penetration of "Cyberspace Security" B module of Shandong secondary vocational group (analysis)
Write a script that can run in Bash / shell and PowerShell
Learning notes: what are the common array APIs that change the original array or do not change the original array?
Opencv image processing
Usage of the formatter attribute of El table
【荧光字效果】
挡不住了,纯国产PC已就位,美国的软硬件体系垄断正式被破
新增市场竞争激烈,中国移动被迫推出限制性超低价5G套餐
I finished watching this video on my knees at station B
苹果独占鳌头,三星大举复兴,国产手机在高端市场颗粒无收
MySQL 5.7.25 source code installation record
Matlab Simulink realizes fuzzy PID control of time-delay temperature control system of central air conditioning
JS continuous assignment operation
Cloud native (36) | introduction and installation of harbor in kubernetes
The diagram of user login verification process is well written!
Spolicy request case
Basic knowledge of website design