我们都知道.start()可以启动多线程,使线程进入就绪状态,但是不一定会立即执行。
以下的代码,如果别人问你是A线程先启动,还是B线程先启动,那就要注意他说的启动是什么含义。因为start翻译成中文就是启动。.start()也叫启动线程
A线程先启动,还是B线程先启动?
答案有两个:但说的都是同一件事
答案1:代码从上往下执行的,A线程先启动(指先调用了.start()方法),B线程再启动(后调用.start()方法),但AB线程中的run方法的执行顺序是不确定的,可能A先,可能B先
答案2.随机的,可能A先启动,可能B先(这个启动指的就是run方法的调用了)
大部分人说的启动都是第二种意思:指的是run方法的调用。
我个人偏向第一种解释:把线程的启动和执行概念分开比较好。
.start()方法调用表示启动线程,进入就绪状态。线程具体什么时候执行,不确定。
结论:
多线程的创建/启动是按顺序执行的,主线程会从上往下执行。
多线程的执行顺序是不确定的,谁抢到谁执行
代码验证,循环启动10个线程,每个线程输出当前线程的名字,这里我取了个巧,将i的值设置成当前线程的名字
public class Test {
public static void main(String[] args) throws InterruptedException {
int i;
for (i = 1; i <= 10; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName());
}, String.valueOf(i)).start();
System.out.println("此线程已启动,当前线程是" + i);
}
}
}
虽然每次输出结果都不一样,但万变不离其宗,结论都是一样的:
- 多线程的启动是按顺序执行的,主线程会从上往下依次启动线程
- 虽然多线程的执行顺序是不确定的,但有一点可以确定:线程要先启动后才有机会执行。换句话说,当cpu从main线程切换到其他线程时,会在已启动的线程中,随机抽一个线程来执行。线程要是启动的慢,肯定轮不到你来执行。
此线程已启动,当前线程是1
1
此线程已启动,当前线程是2
此线程已启动,当前线程是3
此线程已启动,当前线程是4
3
2
此线程已启动,当前线程是5
此线程已启动,当前线程是6
此线程已启动,当前线程是7
4
此线程已启动,当前线程是8
5
此线程已启动,当前线程是9
此线程已启动,当前线程是10
6
7
9
10
8
Process finished with exit code 0
解释清楚很简单,线程有五个状态:新建、就绪、运行、阻塞、死亡.
- new Thread(),该线程就是新建状态。创建线程和启动线程都是顺序执行的,未创建的线程当然没有资格去抢cpu执行权。
- .start()方法使线程进入就绪状态,这个线程有资格执行。就绪状态中的线程去抢cpu执行权,获取到cpu执行权后,线程进入运行状态,开始调用自己的run方法。
看的更明显一点:
public class Test {
public static void main(String[] args) throws InterruptedException {
int i;
for (i = 1; i <= 10; i++) {
System.out.println("main线程:准备创建线程" + i);
new Thread(() -> {
System.out.println("main线程已切换到其余线程:"+Thread.currentThread().getName()+"已抢到cpu执行权");
}, String.valueOf(i)).start();
System.out.println("main线程:"+i+"线程已创建,"+i+"线程进入就绪状态");
}
System.out.println("main线程执行完毕");
}
<