Thread.join()笔记,thread.join笔记
Thread.join()笔记,thread.join笔记
首先看下javadoc的介绍
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join--
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join-long-
https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#join-long-int-
从javadoc的介绍可以看出,Thread.join()方法就是要等待线程结束。
具体实现方法:循环的检查Thread.isAlive(),如果返回true,则进入Thread.wait();等待线程执行完毕后,Thread.notifyAll()会被触发,然后检查Thread.isAlive(),此时会返回false,Thread.join()方法返回。
看一下Thread.join()方法的源代码:
public final void join() throws InterruptedException {
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");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
核心代码:
while (isAlive()) {
wait(0);
}
且join()方法具有synchronized标识,进入join()方法需要获取Thread对象的锁。
如果进入join()方法时,线程已经执行结束,那么isAive()方法返回false,join()方法直接返回;
如果进入join()方法时,线程还在执行,那么isAlive()方法返回true,进入wait(),线程执行结束退出时,JVM会调用Thread.notifyAll()方法,唤醒wait()中的线程,join()方法返回。
从openjdk源码中可以看到调用Thread.notifyAll()的地方:openjdk\hotspot\src\share\vm\runtime\thread.cpp中的JavaThread::exit(bool destroy_vm, ExitType exit_type)方法中的ensure_join()
void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
assert(this == JavaThread::current(), "thread consistency check");
HandleMark hm(this);
Handle uncaught_exception(this, this->pending_exception());
this->clear_pending_exception();
Handle threadObj(this, this->threadObj());
assert(threadObj.not_null(), "Java thread object should be created");
if (get_thread_profiler() != NULL) {
get_thread_profiler()->disengage();
ResourceMark rm;
get_thread_profiler()->print(get_thread_name());
}
......
// 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);
assert(!this->has_pending_exception(), "ensure_join should have cleared");
// 6282335 JNI DetachCurrentThread spec states that all Java monitors
// held by this thread must be released. A detach operation must only
// get here if there are no Java frames on the stack. Therefore, any
// owned monitors at this point MUST be JNI-acquired monitors which are
// pre-inflated and in the monitor cache.
//
// ensure_join() ignores IllegalThreadStateExceptions, and so does this.
if (exit_type == jni_detach && JNIDetachReleasesMonitors) {
assert(!this->has_last_Java_frame(), "detaching with Java frames?");
ObjectSynchronizer::release_monitors_owned_by_thread(this);
assert(!this->has_pending_exception(), "release_monitors 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);
}
相关文章
- 暂无相关文章
用户点评