join在线程里面意味着“插队”,哪个线程调用join代表哪个线程插队先执行——但是插谁的队是有讲究了,不是说你可以插到队头去做第一个吃螃蟹的人,而是插到在当前运行线程的前面,比如系统目前运行线程A,在线程A里面调用了线程B.join方法,则接下来线程B会抢先在线程A面前执行,等到线程B全部执行完后才继续执行线程A。
而在JDK的解释中,join方法被解释成等待这个线程死亡,也就是等待这个线程全部执行完后才继续执行接下来的进程。
public class Test1 implementsRunnable{
@Overridepublic voidrun() {for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}public static void main(String[] args) throwsInterruptedException {
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 implementsRunnable{
@Overridepublic voidrun() {for (int i = 0; i < 20; i++) {
System.out.println(Thread.currentThread().getName()+i);
}
}public static void main(String[] args) throwsInterruptedException {
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 classTest{public static void main(String[] args) throwsInterruptedException {//开启Father线程,满足Father需求
new Thread(newFather()).start();
}
}class Father implementsRunnable{
@Overridepublic voidrun() {
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 implementsRunnable{
@Overridepublic voidrun() {
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("儿子不见了,报警寻找");
}