当前位置:网站首页>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 ...
边栏推荐
- 测试用例和bug描述规范参考
- Tool classes for extracting zip files
- Subtractive integer (number theory)
- Distributed transaction solution 2: message queue to achieve final consistency
- Chapter 8 - two basic problems of data processing
- (十二)交互组件Selectable
- EIP-1559
- 还在原地踏步,提高软件测试能力的方法你知道吗?
- Basic exercise letter graphics
- Codecraft-22 and codeforces round 795 (Div. 2)
猜你喜欢

Do you know the meaning behind these questions?

MySQL安装
帮助你拿到offer的金融测试面试题

Machine learning notes - circular neural network memo list

解压缩zip文件的工具类

Distributed transaction solution 2: message queue to achieve final consistency

Introduction to applet cloud development -- questionnaire evaluation applet practice (7)

2022 melting welding and thermal cutting test questions and answers

Tool classes for extracting zip files

Unittest test framework
随机推荐
Basic exercise letter graphics
软件测试面试题精选
网页中加载二次元3D虚拟主播源码(1:项目介绍和源码)
Do you know the meaning behind these questions?
Change tabledata column name
Notes on data mining in Tsinghua University (1)
Chapter V -[bx] and loop instructions
Visualization of two-dimensional feature logistic regression prediction results
Solve the problem that when unity is opened, you will be prompted that the project has been opened, but you have not opened it before (it may be closed abnormally before)
Counting haybales (difference + discretization)
Codecraft-22 and codeforces round 795 (Div. 2)
Mycat的使用
Minimum transfer times
Quick sort
Test case and bug description specification reference
Leetcode 336 palindrome pair (palindrome string + hash)
128. Plus longue séquence continue - table de hachage
(14) Inputfield logic analysis
What are the design principles of an automated test framework? I'll sum it up for you. Come and see
Countdownlatch example