温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java开源工具在linux上执行的线程是什么

发布时间:2022-01-06 22:12:08 来源:亿速云 阅读:131 作者:iii 栏目:编程语言

本篇内容介绍了“Java开源工具在linux上执行的线程是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Attach Listener 线程都只是操作socket文件,并没有去执行比如stack 分析,或者heap的分析,真正的工作线程其实是vm thread.

(一)启动vm thread

jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {  ...    // Create the VMThread    { TraceTime timer("Start VMThread", TraceStartupTime);      VMThread::create();      Thread* vmthread = VMThread::vm_thread();       if (!os::create_thread(vmthread, os::vm_thread))        vm_exit_during_initialization("Cannot create VM thread. Out of system resources.");       // Wait for the VM thread to become ready, and VMThread::run to initialize      // Monitors can have spurious returns, must always check another state flag      {        MutexLocker ml(Notify_lock);        os::start_thread(vmthread);        while (vmthread->active_handles() == NULL) {          Notify_lock->wait();        }      }    }  ...    }

我们可以看到,在thread.cpp里启动了线程vm thread,在这里我们同时也稍微的略带的讲一下jvm在linux里如何启动线程的。

通常在linux中启动线程,是调用:

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

而在java里却增加了os:create_thread --初始化线程 和os:start_thread--启动线程。

我们去看一下jvm里面是如何在linux里做到的。

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

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

继续看java_start方法:

static void *java_start(Thread *thread) {  ....    // handshaking with parent thread    {      MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);       // notify parent thread      osthread->set_state(INITIALIZED);      sync->notify_all();       // wait until os::start_thread()      while (osthread->get_state() == INITIALIZED) {        sync->wait(Mutex::_no_safepoint_check_flag);      }    }     // call one more level start routine    thread->run();     return 0;  }

首先jvm先设置了当前线程的状态是Initialized, 然后notify所有的线程,

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

不停的查看线程的当前状态是不是Initialized, 如果是的话,调用了sync->wait()的方法等待。

来看os:start_thread的方法 os.cpp

void os::start_thread(Thread* thread) {    // guard suspend/resume    MutexLockerEx ml(thread->SR_lock(), Mutex::_no_safepoint_check_flag);    OSThread* osthread = thread->osthread();    osthread->set_state(RUNNABLE);    pd_start_thread(thread);  }

这时候设置了线程的状态为runnable,但没有notify线程。

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

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

这时候我们看到了notify 线程的操作,也就是这时候notify了线程,因为这时候的线程的状态是RUNNABLE, 方法java_start继续往下执行,于是调用了thread->run()的方法。

对于线程vm Thread 也就是调用了vmthread::run方法。

vmThread.cpp

void VMThread::run() {  ...  this->loop();  ...  }

调用了loop函数,处理了VM_Operation 的queue 

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

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

static jint thread_dump(AttachOperation* op, outputStream* out) {    bool print_concurrent_locks = false;    if (op->arg(0) != NULL && strcmp(op->arg(0), "-l") == 0) {      print_concurrent_locks = true;    }     // thread stacks    VM_PrintThreads op1(out, print_concurrent_locks);    VMThread::execute(&op1);     // JNI global handles    VM_PrintJNI op2(out);    VMThread::execute(&op2);     // Deadlock detection    VM_FindDeadlocks op3(out);    VMThread::execute(&op3);     return JNI_OK;  }

简单看一下类VM_PrintThreads 它 继承了VM_Operation

class VM_PrintThreads: public VM_Operation {   private:    outputStream* _out;    bool _print_concurrent_locks;   public:    VM_PrintThreads()                                                { _out = tty; _print_concurrent_locks = PrintConcurrentLocks; }    VM_PrintThreads(outputStream* out, bool print_concurrent_locks)  { _out = out; _print_concurrent_locks = print_concurrent_locks; }    VMOp_Type type() const                                           {  return VMOp_PrintThreads; }    void doit();    bool doit_prologue();    void doit_epilogue();  };

当调用VMThread::execute()也就是将VM_PrintThreads 放入了_vm_queue中,交给vm thread 处理,对vm thread来说取出queue里的VM_Operation,并且调用doit方法。

在jstack里,attach listener 的线程产生了VM_PrintThreads,VM_PrintJNI,VM_FindDeadlocks 3个operations,交给了vm thread 的线程处理。

“Java开源工具在linux上执行的线程是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI