线程start方法和join方法之间的代码执行顺序
线程调用start()方法之后,进入就绪状态,等待cpu分配时间片。
join方法原理
可知:当系统运行到X.join方法时,调用该方法的线程被wait(),直到X线程跑完。
public class TestThreadState {
public static void main(String[] args) {
System.out.println("爸爸和儿子买烟故事");
Thread father = new Thread(new FatherThread());
father.start();
}
}
class FatherThread implements Runnable {
public void run() {
System.out.println("爸爸想抽烟,发现烟抽完了");
System.out.println("爸爸让儿子去买包红塔山");
Thread son = new Thread(new SonThread());
son.start();
System.out.println("爸爸等儿子买烟回来");
try {
son.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("爸爸出门去找儿子跑哪去了");
// 结束JVM。如果是0则表示正常结束;如果是非0则表示非正常结束
System.exit(1);
}
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子");
}
}
class SonThread implements Runnable {
public void run() {
System.out.println("儿子出门去买烟");
System.out.println("儿子买烟需要10分钟");
try {
for (int i = 1; i <= 10; i++) {
System.out.println("第" + i + "分钟");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("儿子买烟回来了");
}
}
上代码运行时,“爸爸等儿子买烟回来”是否可能在“儿子出门去买烟”之后打印呢?
将代码稍作修改
public class TestThreadState {
public static void main(String[] args) {
System.out.println("爸爸和儿子买烟故事");
Thread father = new Thread(new FatherThread());
father.start();
}
}
class FatherThread implements Runnable {
public void run() {
System.out.println("爸爸想抽烟,发现烟抽完了");
System.out.println("爸爸让儿子去买包红塔山");
Thread son = new Thread(new SonThread());
son.start();
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
System.out.println("爸爸等");
try {
son.join();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("爸爸出门去找儿子跑哪去了");
System.exit(1);
}
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子1");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子2");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子3");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子4");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子5");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子6");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子7");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子8");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子9");
System.out.println("爸爸高兴的接过烟开始抽,并把零钱给了儿子10");
}
}
class SonThread implements Runnable {
public void run() {
System.out.println("儿子出门去买烟");
System.out.println("儿子买烟需要3分钟");
try {
for (int i = 1; i <= 3; i++) {
System.out.println("第" + i + "分钟");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("儿子买烟回来了");
}
}
多次运行,得到如下结果:
爸爸和儿子买烟故事
爸爸想抽烟,发现烟抽完了
爸爸让儿子去买包红塔山
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
儿子出门去买烟
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
爸爸等
儿子买烟需要3分钟
第1分钟
第2分钟
第3分钟
儿子买烟回来了
爸爸高兴的接过烟开始抽,并把零钱给了儿子1
爸爸高兴的接过烟开始抽,并把零钱给了儿子2
爸爸高兴的接过烟开始抽,并把零钱给了儿子3
爸爸高兴的接过烟开始抽,并把零钱给了儿子4
爸爸高兴的接过烟开始抽,并把零钱给了儿子5
爸爸高兴的接过烟开始抽,并把零钱给了儿子6
爸爸高兴的接过烟开始抽,并把零钱给了儿子7
爸爸高兴的接过烟开始抽,并把零钱给了儿子8
爸爸高兴的接过烟开始抽,并把零钱给了儿子9
爸爸高兴的接过烟开始抽,并把零钱给了儿子10
Process finished with exit code 0
可知,start和join方法之间的代码可能会在插队之前执行。
建议start方法后紧跟join方法,否则执行顺序不受控制