当前位置:网站首页>30 minutes to thoroughly understand the synchronized lock upgrade process
30 minutes to thoroughly understand the synchronized lock upgrade process
2022-07-27 03:20:00 【Fat technology house】
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 0
Through 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 .
边栏推荐
- Abbkine AbFluor 488 细胞凋亡检测试剂盒特点及实验建议
- How big is the bandwidth of the Tiktok server for hundreds of millions of people to brush at the same time?
- Common events of window objects
- 【flask】服务端获取客户端请求的文件
- After two years of graduation, I switched to software testing and got 12k+, and my dream of not taking the postgraduate entrance examination with a monthly salary of more than 10000 was realized
- be based on. NETCORE development blog project starblog - (16) some new functions (monitoring / statistics / configuration / initialization)
- localStorage与sessionStorage
- Attention should be paid to the first parameter of setTimeout
- Coco test dev test code
- 消息被拒MQ
猜你喜欢

Idea 中添加支持@Data 插件

$128million! IQM, a Finnish quantum computing company, was supported by the world fund

Make ppt timeline

Social wechat applet of fanzhihu forum community

C语言const用法详解

商城小程序项目完整源码(微信小程序)

Portraiture5全新升级版磨皮滤镜插件神器

消息被拒MQ

Source code analysis of warning notification for skywalking series learning

Integrated water conservancy video monitoring station telemetry terminal video image water level water quality water quantity flow velocity monitoring
随机推荐
Okaleido tiger is about to log in to binance NFT in the second round, which has aroused heated discussion in the community
带你了解什么是 Web3.0
数据湖(二十):Flink兼容Iceberg目前不足和Iceberg与Hudi对比
On the prototype of constructor
Hcip 13th day notes
Social wechat applet of fanzhihu forum community
[binary search medium] leetcode 34. find the first and last positions of elements in the sorted array
{“errcode“:44001,“errmsg“:“empty media data, hint: [1655962096234893527769663], from ip: 222.72.xxx.
二叉树(北京邮电大学机试题)(DAY 85)
C语言const用法详解
注解@Autowired和@Resource的区别总结
My crawler notes (VII) blog traffic +1 through Crawlers
Does Oracle have a distributed database?
2513: 小勇学分数(公约数问题)
子模块cache缓存失效
安全员及环保员岗位职责
周全的照护 解析LYRIQ锐歌电池安全设计
字节一面:TCP 和 UDP 可以使用同一个端口吗?
be based on. NETCORE development blog project starblog - (16) some new functions (monitoring / statistics / configuration / initialization)
CAS deployment and successful login jump address