版权声明:作者:N3verL4nd 出处: https://blog.csdn.net/lgh1992314/article/details/80070515
/**
* Waits at most {@code millis} milliseconds for this thread to
* die. A timeout of {@code 0} means to wait forever.
* 等待该线程终止的时间最长为 millis 毫秒
* millis 为 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()) {
// 使调用 join 方法的线程(持有该线程对象的锁)进入阻塞状态(WAITING)
wait(0);
}
} else {
// 有时间等待,如果当前线程还没有结束,则不再等待
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
// // 使调用 join 方法的线程(持有该线程对象的锁)进入阻塞状态(TIMED_WAITING)
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
/**
* 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒
*/
public final synchronized void join(long millis, int nanos)
throws InterruptedException {
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
millis++;
}
join(millis);
}
/**
* 等待该线程终止
* 等价于调用: join(0)
* 如果任何线程中断了当前线程,则抛出 InterruptedException 异常
* 当抛出该异常时,当前线程的中断状态 被清除。
*/
public final void join() throws InterruptedException {
join(0);
}
对于 synchronized(无论是作为方法的修饰符还是作为一个语句):哪个线程正在执行这个方法,就是哪个线程获取这个锁。
既然 join 方法的实现是wait
,那么必然会有调用notify
。这是JVM替我们调用的。
作者:cao
链接:https://www.zhihu.com/question/44621343/answer/97640972
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//一个c++函数:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;
//这家伙是啥,就是一个线程执行完毕之后,jvm会做的事,做清理啊收尾工作,
//里面有一个贼不起眼的一行代码,眼神不好还看不到的呢,就是这个:
ensure_join(this);
//翻译成中文叫 确保_join(这个);代码如下:
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
//同志们看到了没,别的不用看,就看这一句,妈了个淡淡,
lock.notify_all(thread);
thread->clear_pending_exception();
}
举个栗子:
import java.util.concurrent.TimeUnit;
public class Main1 {
public static void main(String[] args) {
Thread thread = new Thread(() ->{
for (int i = 0; i < Integer.MAX_VALUE; i++) {
System.out.println(i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(-1);
}
}
假设没有调用thread.join();
,则 thread 线程没有输出。
咦,这不就是 Junit 不支持多线程测试的解决方案么?=。=
https://blog.csdn.net/x_iya/article/details/77877897