歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> JVM Thread stop 的源碼分析

JVM Thread stop 的源碼分析

日期:2017/3/1 10:40:25   编辑:Linux編程

在JVM, Thread.stop 是被阻止的方法,看原語義

該方法具有固有的不安全性。用 Thread.stop 來終止線程將釋放它已經鎖定的所有監視器(作為沿堆棧向上傳播的未檢查 ThreadDeath 異常的一個自然後果)。如果以前受這些監視器保護的任何對象都處於一種不一致的狀態,則損壞的對象將對其他線程可見,這有可能導致任意的行為。stop 的許多使用都應由只修改某些變量以指示目標線程應該停止運行的代碼來取代。目標線程應定期檢查該變量,並且如果該變量指示它要停止運行,則從其運行方法依次返回。如果目標線程等待很長時間(例如基於一個條件變量),則應使用 interrupt方法來中斷該等待。有關更多信息,

而interrupt的語義適合等待中的打斷,如何停止線程是個有意思的話題,先來看看jvm 阻止的thread.stop如何實現

Thread.stop 主要是調用 jvm.cpp,JVM_StopThread 方法,

Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));

對調用thread.stop 非本線程的時候,需要把ThreadDeath異步的發到想要停止的線程。

  1. // Enqueue a VM_Operation to do the job for us - sometime later
  2. void Thread::send_async_exception(oop java_thread, oop java_throwable) {
  3. VM_ThreadStop* vm_stop = new VM_ThreadStop(java_thread, java_throwable);
  4. VMThread::execute(vm_stop);
  5. }

VM_ThreadStop 是一個vm_operations.cpp裡定義的一個operation.

在jvm裡面有一個內部線程叫VM_Thread, 專門負責和處理這些opertaion

"VM Thread" prio=10 tid=0x00007f9de3549800 nid=0x722 runnable

也就是停止線程的事件,並不是當前線程處理的,而是交給VM thread 這個線程處理 在 VMThread 的結構體裡有一個_vm_queue 的VMOperationQueue結構體, 而vm_operation的操作會被放入到VMOperationQueue裡的_queue優先級的隊列中. 在JVM裡面定義了3種優先級隊列 SafepointPriority == 0 MediumPriority == 1 nof_priorities =2 而如何定義哪個優先級別,這裡的算法很有意思,就是算queue的長度,如果<10了那麼將認為SafepointPriority 為high priority 否則就認為MediumPriority 是high priority VmThread 本身是一個自輪詢的線程,具體實現方法見vmThread.cpp. void VMThread::loop()

在方法裡輪詢_vm_queue,把queue優先級隊列(如何判斷優先級見上面的注釋)裡的第一個vm_operation設置到_cur_vm_operation,並把數組中的所有SafepointPriority級別的vm_opration drain到另一個鏈表結構的_drain_list,執行_cur_vm_operation和_drain_list 裡的VM_Operation的evaluate方法。

VM_Operation有4種模式

  1. enum Mode {
  2. _safepoint, // blocking, safepoint, vm_op C-heap allocated
  3. _no_safepoint, // blocking, no safepoint, vm_op C-Heap allocated
  4. _concurrent, // non-blocking, no safepoint, vm_op C-Heap allocated
  5. _async_safepoint // non-blocking, safepoint, vm_op C-Heap allocated
  6. };

而VM_ThreadStop 定義為_async_safepoint,是屬於SafepointPriority的優先級別

VM_Operation->evaluate方法,最後是調用VM_ThreadStop doit()

  1. void VM_ThreadStop::doit() {
  2. assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
  3. JavaThread* target = java_lang_Thread::thread(target_thread());
  4. // Note that this now allows multiple ThreadDeath exceptions to be
  5. // thrown at a thread.
  6. if (target != NULL) {
  7. // the thread has run and is not already in the process of exiting
  8. target->send_thread_stop(throwable());
  9. }
  10. }

最後是把throwable的error,也就是設置Thread裡的_pending_async_exception為threaddeath,設置線程的_special_runtime_exit_condition 的狀態設置為_async_exception,同時設置線程的_suspend_flags值為_has_async_exception。

注意在這裡只是設置了異步的exception,和設置了運行退出的狀態為_async_exception, 並沒有直接設置_pending_exception,也就是說要終止的線程運行過程中發現有has_async_exception 執行check_and_handle_async_exceptions,才把_pending_async_exception賦值到_pending_exception,被線程執行並拋出這個異常。

因為thread 當前狀態有可能在wait/sleep, 所以同時interrupt線程。

Copyright © Linux教程網 All Rights Reserved