"
代码一:
public static void main(String[] args) throws Exception { Thread thread = new Thread(() -> { try { TimeUnit.SECONDS.sleep(10); System.out.println("thread-0 thread exit."); } catch (InterruptedException e) { e.printStackTrace(); } }, "thread-0"); thread.start(); thread.join(); System.out.println("main thread exit."); }
控制台(10s后打印并退出):
thread-0 thread exit.
main thread exit.
Process finished with exit code 0
代码二:
public static void main(String[] args) throws Exception {
Thread.currentThread().join();
System.out.println("main thread exit.");
}
控制台(一直等待中):
问题:第一段代码是main
线程阻塞在thread-0
线程上,当thread-0
执行完毕,main
线程也同时退出,那第二段代码中main
线程阻塞在哪个线程上呢,为什么没有退出?
"
public static void main(String[] args) throws Exception { Thread.currentThread().join(); System.out.println("main thread exit."); }
为了了解问题本质,我们跟进去代码看看,线程的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;
}
}
}
根据代码,其实join方法最终是待用了wait(0);这行代码,而wait方法是本地方法.
根据wait的方法定义,有以下几点逐一说明:
<ul>
<li>Some other thread invokes the {@code notify} method for this
object and thread <var>T</var> happens to be arbitrarily chosen as
the thread to be awakened.
<li>Some other thread invokes the {@code notifyAll} method for this
object.
<li>Some other thread {@linkplain Thread#interrupt() interrupts}
thread <var>T</var>.
<li>The specified amount of real time has elapsed, more or less. If
{@code timeout} is zero, however, then real time is not taken into
consideration and the thread simply waits until notified.
</ul>
因此,回答你的问题就是,join方法实质是调用了wait方法.wait方法调用后阻塞(我不认为这是阻塞)在当前线程(main线程上),根据wait的定义,不调用notify,notifyAll,interrupt以及超时机制(本例调用的是wait(0),故不存在这种情况),那么线程将一直处于等待状态,故一直不会退出。
######main线程阻塞自己
######大致的说下吧,Thread中,join()方法的作用是调用线程等待该线程完成后,才能继续用下运行。
public static void main(String[] args) throws InterruptedException
{
System.out.println("main start");
Thread t1 = new Thread(new Worker("thread-1"));
t1.start();
t1.join();
System.out.println("main end");
}
在上面的例子中,main线程要等到t1线程运行结束后,才会输出“main end”。如果不加t1.join(),main线程和t1线程是并行的。而加上t1.join(),程序就变成是顺序执行了。
我们在用到join()的时候,通常都是main线程等到其他多个线程执行完毕后再继续执行。其他多个线程之间并不需要互相等待。
下面这段代码并没有实现让其他线程并发执行,线程是顺序执行的。
public static void main(String[] args) throws InterruptedException
{
System.out.println("main start");
Thread t1 = new Thread(new Worker("thread-1"));
Thread t2 = new Thread(new Worker("thread-2"));
t1.start();
//等待t1结束,这时候t2线程并未启动
t1.join();
//t1结束后,启动t2线程
t2.start();
//等待t2结束
t2.join();
System.out.println("main end");
}
所以就会是这个结果
"版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。