join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A,在线程A里面调用了线程B.join方法,则接下来线程B会抢先在线程A面前执行,等到线程B全部执行完后才继续执行线程A。

而在JDK的解释中,join方法被解释成等待这个线程死亡,也就是等待这个线程全部执行完后才继续执行接下来的进程。

public class Test1 implements Runnable{

    @Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
} public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new Test1(),"线程一");
Thread thread2=new Thread(new Test1(),"线程二");
Thread thread3=new Thread(new Test1(),"线程三");
thread1.start();
thread2.start();
thread3.start(); System.out.println("------------------主线程到此-------------------");
/*thread2.join(); */ for (int i = 0; i < 20; i++) {
System.out.println("主线程"+i);
}
} }

在上面这个例子中,在主线程里面开启了3个子线程,结果是主线程先执行完再执行其他线程。

加上让线程2先执行完再执行主线程join后

public class Test1 implements Runnable{

    @Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
} public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new Test1(),"线程一");
Thread thread2=new Thread(new Test1(),"线程二");
Thread thread3=new Thread(new Test1(),"线程三");
thread1.start();
thread2.start();
thread3.start(); System.out.println("------------------主线程到此-------------------");
thread2.join(); //让线程2先执行完主线程才能继续执行 for (int i = 0; i < 20; i++) {
System.out.println("主线程"+i);
}
} }

结果是

/**
* join的用法,哪个线程调用join哪个线程就插队先执行
*/ public class Test{ public static void main(String[] args) throws InterruptedException {
//开启Father线程,满足Father需求
new Thread(new Father()).start();
} } class Father implements Runnable{ @Override
public void run() {
System.out.println("老爸要抽烟,发现没烟了,给了100块让儿子去买中华......");
Thread son=new Thread(new Son()); //让儿子去买烟
son.start(); //开启儿子线程后,儿子线程进入就绪状态等待CPU调度,不一定立即执行儿子线程,所以可能会出现儿子没把烟买回来老爸就有烟抽了
/* try {
son.join(); //让儿子先插队去买烟
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("儿子不见了,报警寻找");
}*/
System.out.println("老爸接过烟,把零钱给了儿子");
System.out.println("儿子很开心,出门去了游戏厅");
}
} class Son implements Runnable{ @Override
public void run() {
System.out.println("儿子接过钱蹦跶出了门");
System.out.println("路过游戏厅玩了10秒钟");
for (int i = 1; i <= 10; i++) {
System.out.println(i+"秒");
try {
Thread.sleep(1000); //此时休眠可能会让其他线程进行,出错率增加,通过join方法解决
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("赶紧去买烟");
System.out.println("回家把烟给老爸");
}
}

加入了join方法后,运行结果正确

try {
son.join(); //让儿子先插队去买烟
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("儿子不见了,报警寻找");
}

最新文章

  1. Spring MVC之@RequestMapping 详解
  2. 7.9 数据注解特性--ForeignKey
  3. [转]彻底征服Word 2007标题多级列表
  4. threading使用心得
  5. Java——各种日期的获取(来自别人分享)
  6. Java笔记(十九)&hellip;&hellip;多线程
  7. 【递归】【3月周赛1】【Problem B】
  8. HDU 5795 A Simple Nim(SG打表找规律)
  9. 【HTML】web语义化
  10. 重构手法之Split Temporary Variable(分解临时变量)
  11. 1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】
  12. LOJ #6509. 「雅礼集训 2018 Day7」C
  13. Java第四次实践作业
  14. 测试开发之Django——No6.Django模板中的标签语言
  15. Python3基础之异常结构
  16. vc++post方式登录网站
  17. jQuery运行方式818
  18. T4生成实体,单张表和多张表
  19. windows桌面通知区域不显示音量图标的解决方法
  20. 详解JQuery Ajax 在asp.net中使用总结

热门文章

  1. jmeter之Ramp-up Period(in seconds)
  2. 【LeetCode】堆 heap(共31题)
  3. solaris11 format zpool
  4. Flask【第10篇】:自定义Form组件
  5. 3. ClustrixDB 操作
  6. java-webuploader+Java如何实现分片+断点续传
  7. HDU 2795 Billboard (线段树单点更新 &amp;&amp; 求区间最值位置)
  8. HDU2196computer
  9. (76)深入浅出Mqtt协议
  10. sublime text3 - vue修改data,视图无更新