网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
};
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
try {
for (int i = 0; i < 5; i++) {
System.out.println(threadName + " loop at " + i);
Thread.sleep(1000);
}
System.out.println(threadName + " end.");
} catch (Exception e) {
System.out.println("Exception from " + threadName + ".run");
}
}
}
public class AThread extends Thread {
BThread bt;
public AThread(BThread bt) {
super(“[AThread] Thread”);
this.bt = bt;
}
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.“);
try {
bt.join();
System.out.println(threadName + " end.”);
} catch (Exception e) {
System.out.println("Exception from " + threadName + “.run”);
}
}
}
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.“);
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);
at.start();
at.join();
} catch (Exception e) {
System.out.println(“Exception from main”);
}
System.out.println(threadName + " end!”);
}
}
运行结果:
main start. – 主线程启动, 因为主线程中调用了at.join(), 所以主线程要等到 AThread线程结束之后才能执行
[BThread] Thread start.
[BThread] Thread loop at 0
[BThread] Thread loop at 1
[AThread] Thread start. – AThread线程启动, 因为AThread线程中调用了bt.join(), 所以AThread线程要等到BThread线程结束之后才能执行
[BThread] Thread loop at 2
[BThread] Thread loop at 3
[BThread] Thread loop at 4
[BThread] Thread end. – BThread线程结束了, AThread线程执行
[AThread] Thread end. – AThread线程结束了, 主线程执行
main end!
2.深入的了解join()的用法:
网上有很多人是这样解释 join()的用法的:”主线程等待子线程的终止“ ,相信有很多人都会这么说,但是这个说法是完全错误的,为什么呢?
请看例子,在上边代码的基础上,我们对TestDemo类做一下改动:
public class TestDemo {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start.");
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);
at.start();
// at.join(); //这里注释掉
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}
运行结果:
main start. – 主线程启动
[BThread] Thread start. – BThread线程启动
[BThread] Thread loop at 0
[BThread] Thread loop at 1
main end! – 主线程结束,(也就是说AThread线程中调用了bt.join()并不会影响到主线程)
[AThread] Thread start. – AThread线程启动, 因为AThread线程中调用了bt.join(), 所以AThread线程要等到BThread线程结束之后才能执行
[BThread] Thread loop at 2
[BThread] Thread loop at 3
[BThread] Thread loop at 4
[BThread] Thread end. – BThread线程结束了, AThread线程执行
[AThread] Thread end.
相信聪明的读者已经猜到为什么说 ”
主线程
等待子线程的终止 “ 的错误原因了吧,正确的说法应该是:”
当前线程
等待子线程的终止“
#### 五、从源码看join()方法
在AThread的run方法里,执行了bt.join();,进入看一下它的JDK源码:
public final void join() throws InterruptedException {
join(0L);
}
然后进入join(0L)方法:
public final synchronized void join(long l)
throws InterruptedException
{
long l1 = System.currentTimeMillis();
long l2 = 0L;
if(l < 0L)
throw new IllegalArgumentException("timeout value is negative");
if(l == 0L)
// 如果线程被生成了,但还未被起动,isAlive()将返回false,调用它的join()方法是没有作用的,将直接继续向下执行。
for(; isAlive(); wait(0L));
else
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!