当前位置:网站首页>30 minutes to thoroughly understand the synchronized lock upgrade process
30 minutes to thoroughly understand the synchronized lock upgrade process
2022-07-27 21:25:00 【Java notes shrimp】
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 :
The most comprehensive java Interview question bank
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 !边栏推荐
- ECCV 2022 | 中科大&京东提出:数据高效的Transformer目标检测器
- Dobot Magician 机器臂-简介
- 中国能否在元宇宙的未来发展中取得突破,占领高地?
- Unity 安装个人免费版
- Using pseudo element before to realize equal scaling of elements
- PHP code audit 5 - XSS vulnerability
- MySQL data recovery process is based on binlog redolog undo
- Win11 user name and password backup method
- 数字引领 规划先行 聚焦智慧规划信息平台建设及应用项目探索实践
- R language uses dplyr package to perform data aggregation statistics, calculate sliding window statistics, calculate sliding group mean, and merge the generated statistical data into the original data
猜你喜欢

Can single mode and multi-mode of industrial switches replace each other?

"Geography language" large model Wenxin Ernie geol and its application

“地理-语言”大模型文心ERNIE-GeoL及应用

Leetcode daily practice - the penultimate node in the linked list

Lidar China's front loading curtain opens, millions of production capacity to be digested

The maximum recommended number of rows for MySQL is 2000W. Is it reliable?

成分句法分析综述(第二版)

The application of building cloud rendering is expanding, and more and more industries are in urgent need of visualization services

Conquer 3 pieces of IT equipment for all programmers →

Leetcode daily practice - 876. Intermediate node of linked list
随机推荐
R language uses LROC function of epidisplay package to visualize ROC curve of logistic regression model and output diagnostic table, visualize multiple ROC curves, and use legend function to add legen
说明书丨Worthington逆转录酶、重组 HIV 检测方案
使用百度飞桨EasyDL实现电商UGC图片自动分类
激光雷达中国前装大幕开启,数百万颗产能待消化
MapGIS三维管线建模,唤醒城市地下管线脉搏
Set up discuz forum and break the stolen database
Traps and limitations of Engineering Technology Development
LabVIEW learning note 5: you cannot return to the original state after pressing the button
Differences among native objects, built-in objects, and host objects
【华为HCIE安全考什么科目?华为HCIE安全考什么知识点?】
R language uses dplyr package to connect two dataframe data (left join)
Troubleshooting and resolution of program operation problems: an instance of 'std:: Logic_ error‘what(): basic_ string::_ M_ construct null not valid
论文赏析[EMNLP18]用序列标注来进行成分句法分析
Win11用户名和密码备份方法
Worthington plasma amine oxidase (PAO) instructions
Implicit intent
PHP代码审计5—XSS漏洞
Big guys, the MySQL version is low and does not support CDC, so canal synchronizes binlog to Kafka and data to cli
[what subjects does Huawei hcie security test? What knowledge points does Huawei hcie security test have?]
Dobot magician robot arm - Introduction