概述
面試時,經(jīng)常會有面試官會問到Thread.join方法是干嗎的?JavaDoc上的結(jié)束很簡單:
Waits for this thread to die.
意思是說等待線程死亡,今天就一起來看看具體的源碼實現(xiàn);
Thread.join
Thread.join方法可以帶參數(shù)梳玫,也可以不帶參數(shù),實際上不帶參數(shù)時相當于調(diào)用Thread.join(0);
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
//參數(shù)為0,調(diào)用Object.wait(0)等待
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);//參數(shù)非0候生,調(diào)用Object.wait(time)等待
now = System.currentTimeMillis() - base;
}
}
}
從上面的源碼可以看到,邏輯實現(xiàn)比較簡單绽昼,通過while循環(huán)查看線程狀態(tài)(isAlive()),如果線程活著唯鸭,調(diào)用Object.wait()方法等待;
那么:
- 如何判斷線程是否活著呢硅确?
- wait()方法是在什么時候被喚醒的呢肿孵?
isAlive是個native方法,具體實現(xiàn)在jvm.cpp文件:
JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))
JVMWrapper("JVM_IsThreadAlive");
oop thread_oop = JNIHandles::resolve_non_null(jthread);
return java_lang_Thread::is_alive(thread_oop);
JVM_END
java_lang_Thread::is_alive在javaClasses.cpp文件定義:
bool java_lang_Thread::is_alive(oop java_thread) {
JavaThread* thr = java_lang_Thread::thread(java_thread);
return (thr != NULL);
}
可以看到是通過Thread的eetop找到內(nèi)部的JavaThread, 如果為NULL,則表示線程已死;
好疏魏,第一個問題得到解決停做,接下來看第二個問題:
在前面的文章Java線程源碼解析之start的最后,說到
當run方法執(zhí)行結(jié)束,會調(diào)用JavaThread::exit方法清理資源
//由于原方法較長大莫,刪除不相關部分
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
ensure_join(this);
assert(!this->has_pending_exception(), "ensure_join should have cleared");
// Remove from list of active threads list, and notify VM thread if we are the last non-daemon thread
Threads::remove(this);
}
static void ensure_join(JavaThread* thread) {
// 獲取Threads_lock
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "java thread object must exist");
ObjectLocker lock(threadObj, thread);
// 忽略pending exception (ThreadDeath)
thread->clear_pending_exception();
//設置java.lang.Thread的threadStatus為 TERMINATED.
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
//清除native線程蛉腌,這將會導致isAlive()方法返回false
java_lang_Thread::set_thread(threadObj(), NULL);
//通知所有等待thread鎖的線程, join的wait方法將返回,由于isActive返回false,join方法將執(zhí)行結(jié)束并返回
lock.notify_all(thread);
}
從上面的源碼實現(xiàn)知道只厘,當run方法執(zhí)行結(jié)束烙丛,會將native線程對象設為null,并且通過notifyAll方法,讓等待在Thread對象鎖上的wait方法返回;因此Thread.join常用于等待線程執(zhí)行完畢羔味,當然如果中間出現(xiàn)異常河咽,join方法也會返回。