xieyj 发表于 2013-2-7 09:35:06

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之后,都和一个操作系统的线程进行绑定。
页: [1]
查看完整版本: java线程启动代码