跟著sleep看jvm執行緒變化
jvm執行緒是維護了執行緒的狀態。new,running,waiting,timed waiting,blocked,terminated。我們透過jstack等工具檢視的時候,執行緒狀態就是上面的一種。jvm本身是做了一種抽象,我們現在從一個典型的方法,來跟蹤檢視一下jvm內部又是怎麼做狀態變化的。
sleep方法入手
public static native void sleep(long millis) throws InterruptedException;
sleep是一個native 方法,我們透過jvm原來來進行跟著(原始碼來自openjdk11)。
根據jni的規範,我們透過包名或者是jni的註冊方式找到了對應的宣告。
static JNINativeMethod methods[] = {
{"start0", "()V", (void *)&JVM_StartThread},
{"stop0", "(" OBJ ")V", (void *)&JVM_StopThread},
{"isAlive", "()Z", (void *)&JVM_IsThreadAlive},
{"suspend0", "()V", (void *)&JVM_SuspendThread},
{"resume0", "()V", (void *)&JVM_ResumeThread},
{"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority},
{"yield", "()V", (void *)&JVM_Yield},
{"sleep", "(J)V", (void *)&JVM_Sleep},
{"currentThread", "()" THD, (void *)&JVM_CurrentThread},
{"countStackFrames", "()I", (void *)&JVM_CountStackFrames},
{"interrupt0", "()V", (void *)&JVM_Interrupt},
{"isInterrupted", "(Z)Z", (void *)&JVM_IsInterrupted},
{"holdsLock", "(" OBJ ")Z", (void *)&JVM_HoldsLock},
{"getThreads", "()[" THD, (void *)&JVM_GetAllThreads},
{"dumpThreads", "([" THD ")[[" STE, (void *)&JVM_DumpThreads},
{"setNativeName", "(" STR ")V", (void *)&JVM_SetNativeThreadName},
};
接下來我們要跟蹤的就是JVM_Sleep了。
我們一點一點來解析這個方法。
首先這裡有宏定義。
JVM_ENTRY(void, JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis))
我們展開JVM_ENTRY。
#define JVM_ENTRY(result_type, header)
extern "C" {
result_type JNICALL header {
JavaThread* thread=JavaThread::thread_from_jni_environment(env);
ThreadInVMfromNative __tiv(thread);
debug_only(VMNativeEntryWrapper __vew;)
VM_ENTRY_BASE(result_type, header, thread)
在ThreadInVMfromNative中,發生了一次執行緒狀態的變更。
class ThreadInVMfromNative : public ThreadStateTransition {
public:
ThreadInVMfromNative(JavaThread* thread) : ThreadStateTransition(thread) {
trans_from_native(_thread_in_vm);
}
~ThreadInVMfromNative() {
trans_and_fence(_thread_in_vm, _thread_in_native);
}
};
在構造方法中把JavaThread的**thread->thread_state()**狀態變為了_thread_in_vm。在解構函式中把狀態改成了_thread_in_native。這裡的__tiv是一個本地物件,只有在棧銷燬的時候才會觸發析構,也就是說這裡的轉為_thread_in_native只不過是一瞬間的事情。
展開頭結束後,我們再繼續往後觀察。
JavaThreadSleepState jtss(thread);
在這個構造方法中。把**java_thread->threadObj()**的狀態變為了java_lang_Thread::SLEEPING
static void set_thread_status(JavaThread* java_thread,
java_lang_Thread::ThreadStatus state) {
java_lang_Thread::set_thread_status(java_thread->threadObj(), state);
}
這裡對應的就是java的執行緒的狀態了。
在往下走就直接設定**thread->osthread()**的狀態為sleep。
ThreadState old_state = thread->osthread()->get_state();
thread->osthread()->set_state(SLEEPING);
狀態到這裡全部設定完成。
狀態梳理
透過上面的程式碼,我們可以發現最核心的就是JavaThread的這個物件,他本身代表的jvm中的執行緒狀態。會標識執行緒是在vm還是執行緒是在java或者在native。具體的狀態如下
enum JavaThreadState {
_thread_uninitialized = 0, // should never happen (missing initialization)
_thread_new = 2, // just starting up, i.e., in process of being initialized
_thread_new_trans = 3, // corresponding transition state (not used, included for completness)
_thread_in_native = 4, // running in native code
_thread_in_native_trans = 5, // corresponding transition state
_thread_in_vm = 6, // running in VM
_thread_in_vm_trans = 7, // corresponding transition state
_thread_in_Java = 8, // running in Java or in stub code
_thread_in_Java_trans = 9, // corresponding transition state (not used, included for completness)
_thread_blocked = 10, // blocked in vm
_thread_blocked_trans = 11, // corresponding transition state
_thread_max_state = 12 // maximum thread state+1 - used for statistics allocation
};
這個類同時那種java執行緒狀態的引用。就是java_thread->threadObj()。這個對應的是java的執行緒狀態,這個也是我們jstack看到的狀態。
"main" #1 prio=5 os_prio=31 tid=0x00007fee9b809000 nid=0xe03 waiting on condition [0x0000700008d65000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.company.Sleep.main(Sleep.java:7)
為什麼輸出的是timed_waiting(sleep),這個主要是因為格式化輸出的原因。
if(status == THREAD_STATUS_NEW){
return "NEW";
}else if(status == THREAD_STATUS_RUNNABLE){
return "RUNNABLE";
}else if(status == THREAD_STATUS_SLEEPING){
return "TIMED_WAITING (sleeping)";
}else if(status == THREAD_STATUS_IN_OBJECT_WAIT){
return "WAITING (on object monitor)";
}else if(status == THREAD_STATUS_IN_OBJECT_WAIT_TIMED){
return "TIMED_WAITING (on object monitor)";
}else if(status == THREAD_STATUS_PARKED){
return "WAITING (parking)";
}else if(status == THREAD_STATUS_PARKED_TIMED){
return "TIMED_WAITING (parking)";
}else if(status == THREAD_STATUS_BLOCKED_ON_MONITOR_ENTER){
return "BLOCKED (on object monitor)";
}else if(status == THREAD_STATUS_TERMINATED){
return "TERMINATED";
}
return "UNKNOWN";
}
在狀態格式化的時候,把sleeping的歸類成為TIMED_WAITING (sleeping)。
於此同時Java Thread還拿著系統的執行緒thread->osthread()。
小結
jvm中起碼有三種狀態的變化,一種是代表的java規範中的執行緒狀態(java_thread->threadObj()),一種是表示的jvm代理的系統執行緒的狀態(thread->osthread()),同時還有jvm執行緒在做轉換的一種狀態,是vm自己的狀態表示。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2819/viewspace-2825709/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 執行緒-sleep()執行緒
- java執行緒執行緒休眠,sleep方法Java執行緒
- Systrace 執行緒 CPU 執行狀態分析技巧 - Sleep 和 Uninterruptible Sleep 篇執行緒
- Informix 執行緒sleep 分析過程ORM執行緒
- 跟著GPT學習Java執行緒中斷機制GPTJava執行緒
- 執行緒篇2:[- sleep、wait、notify、join、yield -]執行緒AI
- 理解JVM(六):執行緒安全和鎖優化JVM執行緒優化
- 一執行緒序員忙著學習技術,二執行緒序員忙著技術變現,你呢?執行緒
- 深入理解JVM(③)執行緒與Java的執行緒JVM執行緒Java
- JVM中的執行緒行為JVM執行緒
- 多執行緒,執行緒類三種方式,執行緒排程,執行緒同步,死鎖,執行緒間的通訊,阻塞佇列,wait和sleep區別?執行緒佇列AI
- Thread執行緒控制之sleep、join、setDaemon方法的用處thread執行緒
- 多執行緒(2)-執行緒同步條件變數執行緒變數
- 跟著練、包會(JVM調優工具)JVM
- 要點提煉| 理解JVM之執行緒安全&鎖優化JVM執行緒優化
- java多執行緒基礎篇(wait、notify、join、sleep、yeild方法)Java執行緒AI
- 從setTimeout/setInterval看JS執行緒JS執行緒
- JVM程式用一個主執行緒來執行main()方法JVM執行緒AI
- 怎麼樣建立的執行緒才是安全的呢?帶著疑問看文章執行緒
- 深入理解JVM(③)再談執行緒安全JVM執行緒
- JVM找出佔用CPU最高的執行緒JVM執行緒
- 從Java到JVM到OS執行緒睡眠JavaJVM執行緒
- 靜態變數在多執行緒環境下的初始化是執行緒安全的嗎?變數執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 多執行緒面試題之sleep()和wait()方法有什麼區別?執行緒面試題AI
- 併發程式設計——執行緒中sleep(),yield(),join(),wait(),notify(),notifyAll()區別程式設計執行緒AI
- javascript執行緒及與執行緒有關的效能優化JavaScript執行緒優化
- 多執行緒06:條件變數執行緒變數
- JVM-執行緒上下文類載入器JVM執行緒
- 執行緒與多執行緒執行緒
- 多執行緒【執行緒池】執行緒
- 執行緒和執行緒池執行緒
- 多執行緒--執行緒管理執行緒
- 執行緒 執行緒池 Task執行緒
- 新手一看就懂的執行緒池!執行緒
- 大郎!快起來看多執行緒啦!執行緒
- 保證執行緒在主執行緒執行執行緒
- java的執行緒、建立執行緒的 3 種方式、靜態代理模式、Lambda表示式簡化執行緒Java執行緒模式