多线程中主线程与子线程执行的顺序
在我们刚刚接触多线程时,所练习的Demo可能会达不到我们期待的运行结果,这其实有两种可能:
第一,是巧合,CPU可能是一直执行完一个线程再去执行另一个线程。所以我们看到的结果一直是没有交替执行的。
解决办法是:把运行的次数放大,10次不行就100次,100次不行就1000次,1000次不行5000次,其实1000次的时候也就差不多出现了交替运行。
//线程任务类
//线程任务类
public class ThreadDemo implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
Thread th1 = new Thread(new ThreadDemo());
Thread th = new Thread(new ThreadDemo());
th.start();
th1.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程:"+i);
}
System.out.println("线程--------------------------------------------------");
}
}
如下的运行结果就不是理想状态的
当我们把线程任务类的循环次数变为10,把测试类的循环变为100,此时的运行结果如下图:
我们看到,三个线程轮流抢占CPU的执行权。这就是我们预测的结果,也是多线程下的理想状态。
第二,是你的程序有问题,比如以下的代码:
//线程任务类
//线程任务类
public class ThreadDemo implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}
//测试类
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
System.out.println("主线程:"+i);
}
System.out.println("线程--------------------------------------------------");
Thread th1 = new Thread(new ThreadDemo());
Thread th = new Thread(new ThreadDemo());
th.start();
th1.start();
}
}
先看运行结果:
从结果中可以看到只有Thread-0和Thread-1线程在交替执行,而主线程是直接运行完毕的,并且是先执行完主线程再执行剩下的两个线程。其实不管我们运行多少次,结果也都是先把主线程执行完再去执行Thread-0和Thread-1线程。
原因:首先,我们必须知道,如果有多个线程在排队,那么CPU的执行权是随机抢占的。所以前提是必须有多个线程。但是无论哪个线程抢占到CPU的执行权,在线程中都是自上而下执行代码。问题就出在这。
刚开始时,只有主线程在使用CPU的执行权,因为其他两个线程还没有被创建,这时主线程的代码就自上而下的去执行。
当主线程的内容执行完毕后,就开始创建并启动其他的线程,此时,栈中有三个线程:主线程、Thread-0和Thread-1线程。但是主线程已经没有了要执行的代码,所以现在相当于只有Thread-0和Thread-1线程在执行,因此我们会看到这两个线程在轮流抢占CPU的执行权来输出他们各自的内容。
解决办法:
把主线程的内容放到子线程启动之后去执行,就会出现三个线程轮流抢占CPU执行权的情况。
代码更改:
public class Test {
public static void main(String[] args) {
Thread th1 = new Thread(new ThreadDemo());
Thread th = new Thread(new ThreadDemo());
th.start();
th1.start();
for (int i = 0; i < 100; i++) {
System.out.println("主线程:"+i);
}
System.out.println("线程--------------------------------------------------");
}
}
结果如下图: