java线程启动代码

      上次写了个《Thread的调用》过于简单,在这以javaThread的启动过程做一个详细分析。

      先从java/lang/Thread.java看起

       public synchronized void start() {

              .....

              start0(); //   start0为本地方法 private native void start0();

              .....

       }

      

       上面start0的具体实现是jvm.cpp中的JVM_StartThread。

       ......

       native_thread = new JavaThread(&thread_entry, sz);

       if (native_thread->osthread() != NULL) {
              native_thread->prepare(jthread);
       }

       .....

       Thread::start(native_thread);

       

       上面传入函数指针thread_entry,thread_entry就是调用Thread.java中的run方法,这就是java程序中只需要new Thread().start,虚拟机就调用run方法的原因。

       static void thread_entry(JavaThread* thread, TRAPS) {
                        HandleMark hm(THREAD);
                        Handle obj(THREAD, thread->threadObj());
                        JavaValue result(T_VOID);
                        JavaCalls::call_virtual(&result,
                                      obj,
                                      KlassHandle(THREAD, SystemDictionary::thread_klass()),
                                      vmSymbolHandles::run_method_name(), //调用用户编写thread类run方法
                                      vmSymbolHandles::void_method_signature(),
                                      THREAD);
        }

        再看new JavaThread(...)这步。

        JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : Thread() {

                 .........

                 os::ThreadType thr_type = os::java_thread;
                 thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
                                                     os::java_thread;
                 os::create_thread(this, thr_type, stack_sz);

        }
        到了os::create_thread这步。

        bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {

               OSThread* osthread = new OSThread(NULL, NULL);

               thread->set_osthread(osthread);

               HANDLE thread_handle =
               (HANDLE)_beginthreadex(NULL,
                           (unsigned)stack_size,
                           (unsigned (__stdcall *)(void*)) java_start,
                           thread,
                           CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION,
                           &thread_id);

               //上面创建线程的时候,线程不自动运行,而是堵塞,直到上面的Thread::start(native_thread)才开始运行

               .............
        }

        再看启动函数java_start。

        static unsigned __stdcall java_start(Thread* thread) {

                   __try {
                          thread->run();  //注意:传入的是javaThread,所以在这调用javaThread::run
                   } __except(topLevelExceptionFilter(
                       (_EXCEPTION_POINTERS*)_exception_info())) {
                   }

        }

        查看

        void JavaThread::run() {

                  .......

                  thread_main_inner();//在里面真正调用用户写的java类run方法

        }

        void JavaThread::thread_main_inner() {

                 this->entry_point()(this, this); //调用传入thread_entry

                 //退出

                 this->exit(false);
                 delete this;

        }

        最后看一下

        void Thread::start(Thread* thread) {

                ........

                os::start_thread(thread); //运行创建时堵塞的线程

        }

       void os::start_thread(Thread* thread) {

                .........

                OSThread* osthread = thread->osthread();
                osthread->set_state(RUNNABLE);
                pd_start_thread(thread);

       }

       void os::pd_start_thread(Thread* thread) {

               //真正恢复操作系统线程运行的代码

               DWORD ret = ResumeThread(thread->osthread()->thread_handle());

       }

       由上面可以看到每个继承java.lang.Thread的类,调用start之后,都和一个操作系统的线程进行绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值