自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java開源工具在linux上的源碼分析(三):執(zhí)行的線程

開發(fā) 后端
在前面的博客中所提到的信號轉(zhuǎn)發(fā)線程,Attach Listener 線程都只是操作socket文件,并沒有去執(zhí)行比如stack 分析,或者h(yuǎn)eap的分析,真正的工作線程其實是vm thread.

在前面的博客中(http://blog.csdn.net/raintungli/article/details/7034005)所提到的信號轉(zhuǎn)發(fā)線程,Attach Listener 線程都只是操作socket文件,并沒有去執(zhí)行比如stack 分析,或者h(yuǎn)eap的分析,真正的工作線程其實是vm thread.

(一)啟動vm thread

  1. jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {  
  2. ...  
  3.   // Create the VMThread  
  4.   { TraceTime timer("Start VMThread", TraceStartupTime);  
  5.     VMThread::create();  
  6.     Thread* vmthread = VMThread::vm_thread();  
  7.  
  8.     if (!os::create_thread(vmthread, os::vm_thread))  
  9.       vm_exit_during_initialization("Cannot create VM thread. Out of system resources.");  
  10.  
  11.     // Wait for the VM thread to become ready, and VMThread::run to initialize  
  12.     // Monitors can have spurious returns, must always check another state flag  
  13.     {  
  14.       MutexLocker ml(Notify_lock);  
  15.       os::start_thread(vmthread);  
  16.       while (vmthread->active_handles() == NULL) {  
  17.         Notify_lock->wait();  
  18.       }  
  19.     }  
  20.   }  
  21. ...  
  22.  
  23.  

我們可以看到,在thread.cpp里啟動了線程vm thread,在這里我們同時也稍微的略帶的講一下jvm在linux里如何啟動線程的。

通常在linux中啟動線程,是調(diào)用:

  1. int pthread_create((pthread_t *__thread, __const pthread_attr_t *__attr,void *(*__start_routine) (void *), void *__arg)); 

而在java里卻增加了os:create_thread --初始化線程 和os:start_thread--啟動線程。

我們?nèi)タ匆幌耲vm里面是如何在linux里做到的。

在os_linux.cpp中來看create_thread的方法:

  1. bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {  
  2. ....  
  3. int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);  
  4. ....  

繼續(xù)看java_start方法:

  1. static void *java_start(Thread *thread) {  
  2. ....  
  3.   // handshaking with parent thread  
  4.   {  
  5.     MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);  
  6.  
  7.     // notify parent thread  
  8.     osthread->set_state(INITIALIZED);  
  9.     sync->notify_all();  
  10.  
  11.     // wait until os::start_thread()  
  12.     while (osthread->get_state() == INITIALIZED) {  
  13.       sync->wait(Mutex::_no_safepoint_check_flag);  
  14.     }  
  15.   }  
  16.  
  17.   // call one more level start routine  
  18.   thread->run();  
  19.  
  20.   return 0;  

首先jvm先設(shè)置了當(dāng)前線程的狀態(tài)是Initialized, 然后notify所有的線程,

  1. while (osthread->get_state() == INITIALIZED) {  
  2.      sync->wait(Mutex::_no_safepoint_check_flag);  
  3.    } 

不停的查看線程的當(dāng)前狀態(tài)是不是Initialized, 如果是的話,調(diào)用了sync->wait()的方法等待。

來看os:start_thread的方法 os.cpp

  1. void os::start_thread(Thread* thread) {  
  2.   // guard suspend/resume  
  3.   MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);  
  4.   OSThread* osthread = thread->osthread();  
  5.   osthread->set_state(RUNNABLE);  
  6.   pd_start_thread(thread);  
  7. }

這時候設(shè)置了線程的狀態(tài)為runnable,但沒有notify線程。

在 pd_start_thread(thread)中, os_linux.cpp中:

  1. void os::pd_start_thread(Thread* thread) {  
  2.   OSThread * osthread = thread->osthread();  
  3.   assert(osthread->get_state() != INITIALIZED, "just checking");  
  4.   Monitor* sync_with_child = osthread->startThread_lock();  
  5.   MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);  
  6.   sync_with_child->notify();  

這時候我們看到了notify 線程的操作,也就是這時候notify了線程,因為這時候的線程的狀態(tài)是RUNNABLE, 方法java_start繼續(xù)往下執(zhí)行,于是調(diào)用了thread->run()的方法。

 

對于線程vm Thread 也就是調(diào)用了vmthread::run方法。

vmThread.cpp

  1. void VMThread::run() {  
  2. ...  
  3. this->loop();  
  4. ...  

調(diào)用了loop函數(shù),處理了VM_Operation 的queue 關(guān)于queue的級別和優(yōu)先級處理算法:可以參考 另一篇博客:http://blog.csdn.net/raintungli/article/details/6553337

(二)Jstack 運行在vm thread里的VM_Operation

jstack 處理也就是在前面博客所提到的attach Listener 線程所做的 operation

  1. static jint thread_dump(AttachOperation* op, outputStream* out) {  
  2.   bool print_concurrent_locks = false;  
  3.   if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {  
  4.     print_concurrent_locks = true;  
  5.   }  
  6.  
  7.   // thread stacks  
  8.   VM_PrintThreads op1(out, print_concurrent_locks);  
  9.   VMThread::execute(&op1);  
  10.  
  11.   // JNI global handles  
  12.   VM_PrintJNI op2(out);  
  13.   VMThread::execute(&op2);  
  14.  
  15.   // Deadlock detection  
  16.   VM_FindDeadlocks op3(out);  
  17.   VMThread::execute(&op3);  
  18.  
  19.   return JNI_OK;  

簡單看一下類VM_PrintThreads 它 繼承了VM_Operation

  1. class VM_PrintThreads: public VM_Operation {  
  2.  private:  
  3.   outputStream* _out;  
  4.   bool _print_concurrent_locks;  
  5.  public:  
  6.   VM_PrintThreads()                                                { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; }  
  7.   VM_PrintThreads(outputStream* out, bool print_concurrent_locks)  { _out = out; _print_concurrent_locks = print_concurrent_locks; }  
  8.   VMOp_Type type() const                                           {  return VMOp_PrintThreads; }  
  9.   void doit();  
  10.   bool doit_prologue();  
  11.   void doit_epilogue();  
  12. }; 

當(dāng)調(diào)用VMThread::execute()也就是將VM_PrintThreads 放入了_vm_queue中,交給vm thread 處理,對vm thread來說取出queue里的VM_Operation,并且調(diào)用doit方法。

在jstack里,attach listener 的線程產(chǎn)生了VM_PrintThreads,VM_PrintJNI,VM_FindDeadlocks 3個operations,交給了vm thread 的線程處理。

原文鏈接:http://blog.csdn.net/raintungli/article/details/7045024

【系列文章】

  1. Java開源工具在linux上的源碼分析(一):跟蹤方式
  2. Java開源工具在linux上的源碼分析(二):信號處理
  3. Java開源工具在linux上的源碼分析(四):safe point
  4. Java開源工具在linux上的源碼分析(五):-F參數(shù)的bug
  5. Java開源工具在linux上的源碼分析(六):符號表的讀取
責(zé)任編輯:林師授 來源: raintungli的博客
相關(guān)推薦

2012-03-02 12:14:19

JavaJstackJmap

2012-03-02 12:20:21

Javajmapjstack

2012-03-02 12:31:50

Javajmapjstack

2012-03-02 12:38:49

Javajmapjstack

2012-03-02 13:29:38

Javajmapjstack

2022-06-26 18:09:43

Linux開源

2010-01-27 09:58:59

Linuxunix程序日志

2012-03-30 11:16:29

JavaVisualVM

2019-10-16 17:00:51

LinuxUbuntuVMware

2018-10-31 15:54:47

Java線程池源碼

2021-03-09 11:25:04

Linux開源工具服務(wù)器

2012-05-22 00:28:21

JavaJava開源開源工具

2022-06-06 14:20:25

個人財務(wù)開源預(yù)算

2021-08-31 09:41:57

LinuxiPhone開源工具

2021-09-01 09:47:25

Linux 工具 開發(fā)

2020-05-09 12:01:40

Linux開源軟件SDN

2019-05-23 14:36:24

LinuxSOSReportxsos

2017-01-12 15:58:17

Linux死鎖分析方法

2022-08-19 11:17:09

Linux

2019-08-01 09:52:46

LinuxNetData性能監(jiān)控工具
點贊
收藏

51CTO技術(shù)棧公眾號