publicstaticvoidmain(String[] args)throws Exception { System.err.println("main thread start... "); Runnable r = new JoinDemo(); Thread t = new Thread(r); t.setName("ibli joinTest ..."); t.start(); // 但是主线程join的超时时间是1s t.join(1000); System.err.println("main thread end... "); } }
执行效果:
1 2 3 4 5 6
main thread start... join thread demo main thread end... Exception in thread "ibli joinTest ..." java.lang.NullPointerException at com.ibli.threadTest.api.JoinDemo.run(JoinDemo.java:14) at java.lang.Thread.run(Thread.java:748)
publicfinalsynchronizedvoidjoin(long millis) throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; // 首先校验参数是否合法 if (millis < 0) { thrownew IllegalArgumentException("timeout value is negative"); }
// 如果join方法没有参数,则相当于直接调用wait方法 if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
void JavaThread::exit(bool destroy_vm, ExitType exit_type) { // Notify waiters on thread object. This has to be done after exit() is called // on the thread (if the thread is the last thread in a daemon ThreadGroup the // group should have the destroyed bit set before waiters are notified). ensure_join(this); }
其中调用ensure_join方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
staticvoidensure_join(JavaThread* thread){ // We do not need to grap the Threads_lock, since we are operating on ourself. Handle threadObj(thread, thread->threadObj()); assert(threadObj.not_null(), "java thread object must exist"); ObjectLocker lock(threadObj, thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway thread->clear_pending_exception(); // Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED. java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); // Clear the native thread instance - this makes isAlive return false and allows the join() // to complete once we've done the notify_all below //这里是清除native线程,这个操作会导致isAlive()方法返回false java_lang_Thread::set_thread(threadObj(), NULL); // 在这里唤醒等待的线程 lock.notify_all(thread); // Ignore pending exception (ThreadDeath), since we are exiting anyway thread->clear_pending_exception(); }