thread.join()
will call thread.wait()
, but who and when notifies (either with thread.notify()
or notifyAll()
) the t
Edit:
Oh, you are talking about inside of the Thread
object itself. Inside of join()
we do see a wait()
. Something like:
while (isAlive()) {
wait(0);
}
The notify()
for this is handled by the Thread
subsystem. When the run()
method finishes, the notify()
is called on the Thread
object. I'm not sure if the code that actually calls notify()
can be seen -- it seems to be done in native code.
No user code needs to call notify()
on that Thread
object. The Java Thread
code handles this internally. Once the thread finishes, the join()
call will return.
For example, the following code will execute fine and the join()
call will return fine without any wait()
or notify()
calls.
Thread thread = new Thread(new Runnable() {
public void run() {
// no-op, just return immediately
}
});
thread.start();
thread.join();
It is important to note that this behavior should probably not be relied upon. The notify()
call is internal to the thread system. You should use join()
if you are waiting for a thread to finish.
As for jdk7 for linux, you can get the answer from the source code of openjdk.
/jdk7/hotspot/src/os/linux/vm/os_linux.cpp
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
static void *java_start(Thread *thread) {
...
thread->run();
return 0;
}
and when start thread in java, the thread will be instanceof JavaThread.
/jdk7/hotspot/src/share/vm/runtime/thread.cpp
void JavaThread::run() {
...
thread_main_inner();
}
void JavaThread::thread_main_inner() {
...
this->exit(false);
delete this;
}
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);
...
}
static void ensure_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
java_lang_Thread::set_thread(threadObj(), NULL);
lock.notify_all(thread);
// Ignore pending exception (ThreadDeath), since we are exiting anyway
thread->clear_pending_exception();
}
so lock.notify_all(thread) will notify all threads whose wait for the thread to finish.