当前位置:网站首页>Implementation of hotspot synchronized
Implementation of hotspot synchronized
2022-06-12 09:19:00 【symop】
One .synchronized Usage and byte compilation
public synchronized void testsynchronized(){
System.out.println("ok");
}
public void testsynchronized1(){
synchronized(Test.class){
System.out.println("ok");
}
}
public void testsynchronized2(){
synchronized(this){
System.out.println("ok");
}
}
utilize javap -v compile , The bytecode information is as follows
public synchronized void testsynchronized();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String ok
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 8: 0
line 9: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 this Lmy/test/Test;
public void testsynchronized1();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: ldc #5 // class my/test/Test
2: dup
3: astore_1
4: monitorenter
5: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
8: ldc #3 // String ok
10: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
13: aload_1
14: monitorexit
15: goto 23
18: astore_2
19: aload_1
20: monitorexit
21: aload_2
22: athrow
23: return
Exception table:
from to target type
5 15 18 any
18 21 18 any
LineNumberTable:
line 11: 0
line 12: 5
line 13: 13
line 14: 23
LocalVariableTable:
Start Length Slot Name Signature
0 24 0 this Lmy/test/Test;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 18
locals = [ class my/test/Test, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
public void testsynchronized2();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: dup
2: astore_1
3: monitorenter
4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
7: ldc #3 // String ok
9: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
12: aload_1
13: monitorexit
14: goto 22
17: astore_2
18: aload_1
19: monitorexit
20: aload_2
21: athrow
22: return
Exception table:
from to target type
4 14 17 any
17 20 17 any
LineNumberTable:
line 16: 0
line 17: 4
line 18: 12
line 19: 22
LocalVariableTable:
Start Length Slot Name Signature
0 23 0 this Lmy/test/Test;
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame */
offset_delta = 17
locals = [ class my/test/Test, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /* chop */
offset_delta = 4
}
synchronized When decorating a code block, it will be compiled into monitorenter and monitorexit The order is right ,monitorenter Used to acquire locks ,monitorexit Used to release locks .
Two .monitorenter Instructions implement
synchronized The lock used is the existence Java The one in the head ,HotSpot The object header of virtual machine mainly includes two parts of data :Mark Word( Tag field ) and Klass Pointer( Class metadata pointer ), among Klass Point Is a pointer to its class metadata , The virtual machine uses this pointer to determine which class instance this object is ,Mark Word Used to store runtime data of the object itself , It's the key to implementing lightweight and biased locks .
Mark Word Used to store runtime data of the object itself , Such as hash code (HashCode)、GC Generational age 、 Lock status flag 、 A lock held by a thread 、 To the thread ID、 Time stamps and so on .
The interpreter performs monitorenter You will enter into InterpreterRuntime.cpp Of InterpreterRuntime::monitorenter Method .
RT_ENTRY_NO_ASYNC(void, InterpreterRuntime::monitorenter(JavaThread* thread, BasicObjectLock* elem))
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
if (PrintBiasedLockingStatistics) {
Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
}
Handle h_obj(thread, elem->obj());
assert(Universe::heap()->is_in_reserved_or_null(h_obj()),
"must be NULL or an object");
if (UseBiasedLocking) {
// Retry fast entry if bias is revoked to avoid unnecessary inflation
ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK);
} else {
ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK);
}
assert(Universe::heap()->is_in_reserved_or_null(elem->obj()),
"must be NULL or an object");
#ifdef ASSERT
thread->last_frame().interpreter_frame_verify_monitor(elem);
#endif
IRT_END
It mainly describes whether the parameter is enabled UseBiasedLocking, If on , Then execute the deflection lock fast_enter Method , Otherwise, execute the lightweight lock slow_enter Method .
1. Biased locking
Purpose : In order to reduce unnecessary lightweight lock execution paths without multi thread contention .
Mark Word The lock identification bit is 01.
void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias, TRAPS) {
if (UseBiasedLocking) {
if (!SafepointSynchronize::is_at_safepoint()) {
BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
return;
}
} else {
assert(!attempt_rebias, "can not rebias toward VM thread");
BiasedLocking::revoke_at_safepoint(obj);
}
assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
}
The main methods are revoke_and_rebias, Too long , Stick it or not , Look not to understand , Just give a general idea .
1. First, judge whether it is at the safe point
2. Determine whether there is lock contention , If there is no lock competition, it will Mark Word The lock identification bit is 01
3. If the lock object is biased and if it is allowed to attempt to acquire a biased lock , Then try to acquire the bias lock again , Otherwise, cancel the bias lock operation
4. Go to this step , Upgrade to lightweight lock
2. Lightweight lock
Purpose : In the competition of multithreading , Reduces the performance cost of traditional heavyweight locks using operating system mutexes .Mark Word The lock identification bit is 00.
void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
markOop mark = obj->mark();
assert(!mark->has_bias_pattern(), "should not see bias pattern here");
if (mark->is_neutral()) {
// Anticipate successful CAS -- the ST of the displaced mark must
// be visible <= the ST performed by the CAS.
lock->set_displaced_header(mark);
if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(), mark)) {
TEVENT (slow_enter: release stacklock) ;
return ;
}
// Fall through to inflate() ...
} else
if (mark->has_locker() && THREAD->is_lock_owned((address)mark->locker())) {
assert(lock != mark->locker(), "must not re-lock the same lock");
assert(lock != (BasicLock*)obj->mark(), "don't relock with same BasicLock");
lock->set_displaced_header(NULL);
return;
}
#if 0
// The following optimization isn't particularly useful.
if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) {
lock->set_displaced_header (NULL) ;
return ;
}
#endif
// The object header will never be displaced to this lock,
// so it does not matter what the value is, except that it
// must be non-zero to avoid looking like a re-entrant lock,
// and must not look locked either.
lock->set_displaced_header(markOopDesc::unused_mark());
ObjectSynchronizer::inflate(THREAD, obj())->enter(THREAD);
}
1.is_neutral Said if biased_lock:0 And lock:01 No lock state .
2. adopt CAS Try to markword Update to point BasicLock Object pointer , If the update is successful , Competition to lock , Then execute the synchronization code .
3. If at present mark In a locked state , And mark Medium ptr Pointer to the stack frame of the current thread , Then execute the synchronization code , Otherwise, multiple threads compete for lightweight locks , Lightweight locks need to be upgraded to heavyweight locks .
To be continued ...
边栏推荐
- NiO principle
- Basic exercise letter graphics
- How should the test plan be written? A thought teaches you
- Chapter 8 - two basic problems of data processing
- Basic exercise decomposing prime factors
- 解决当打开Unity时 提示项目已经打开,而自己之前并没有打开过(可能之前异常关闭)的问题
- After receiving the picture, caigou was very happy and played with PDF. The submission format was flag{xxx}, and the decryption characters should be in lowercase
- Description of string
- Selection of interview questions for software testing
- CodeCraft-22 and Codeforces Round #795 (Div. 2) 题解
猜你喜欢
随机推荐
Do you know how to improve software testing ability?
測試用例和bug描述規範參考
SQL basic syntax II
MySQL安装
day5-x
(十五) TweenRunner
Definition of polar angle and its code implementation
Grab screen and ground glass effect
Source code and scheme for target recognition, detection and 6D attitude estimation (the most advanced method and data set)
Flink CheckPoint : Exceeded checkpoint tolerable failure threshold
帮助你拿到offer的金融测试面试题
ADB command collection, let's learn together
128. 最長連續序列-哈希錶
Test case and bug description specification reference
What are the design principles of an automated test framework? I'll sum it up for you. Come and see
(13) Text rendering text
Four steps for sending rockertmq producer messages
自动化测试框架的设计原则有哪些?我帮你总结好了快来看
NiO principle
Mysql database ignores case






