面试被问线程两次 start,我直接尬住了
本引用仅用学习,禁用商用
引用自 https://mp.weixin.qq.com/s/fJsYrkBIN6QEK_Xwzsz0eg
记得是一个周末,我去面 Java 后端开发岗。面试官上来就猛攻多线程知识,从创建方式到锁机制,一连串问题砸来。还好我提前背了八股文,所以七七八八的也答上来了。
本以为快结束能松口气,面试官冷不丁问:“看过 Thread 源码吗?” 我毫不犹豫的回答看过,紧接着他问:
线程在调用了一次start启动后,再调用一次可以不?如果线程执行完,同样再调用一次start又会怎么样?
当时我支支吾吾,没能答上来。面试结束后,我仔细研究了这个问题,并整理了相关知识点,希望能帮到同样遇到这个难题的朋友。
1. start() 方法的作用
在 Java 中,start() 方法是用来启动线程的。调用 start() 后,JVM 会创建一个新的线程,并执行 run() 方法中的代码。
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程正在运行...");
});
System.out.println(thread.getName() + ":" + thread.getState());
thread.start();
System.out.println(thread.getName() + ":" + thread.getState());
}
}
输出:
Thread-0:NEWThread-0:RUNNABLE线程正在运行...
当我们创建一个Thread实例时,线程处于NEW(新建)状态。此时,调用start()方法会让线程进入RUNNABLE(可运行) 状态,等待CPU调度执行。
这里也补充一个小的知识点:
网上很多八股文面试题中说Java创建线程的方式有3种、4种,或者更多种。准确来说,创建线程只有一种方式那就是:new Thread().start()。
那线程调用两次 start()会发生什么?别急,我们接着看。
2. 调用两次 start()会发生什么?
先来看一段代码:
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程正在运行...");
});
System.out.println(thread.getName() + ":" + thread.getState());
thread.start();
System.out.println(thread.getName() + ":" + thread.getState());
thread.start();
System.out.println(thread.getName() + ":" + thread.getState());
}
}
输出:

第二次调用时,代码抛出IllegalThreadStateException异常。
这是为什么呢?我们跟进start源码中一探究竟!
3. start() 方法的源码分析
以下是 Thread 类中 start() 方法的源码(基于 JDK 1.8):
public class Main {
public synchronized void start() {
// 检查线程状态
if (threadStatus != 0)
throw new IllegalThreadStateException();
// 将线程添加到线程组
group.add(this);
boolean started = false;
try {
// 调用本地方法启动线程
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
// 忽略异常
}
}
}
}
关键点:
- 状态检查:threadStatus 是线程的内部状态标志。若它不等于0表示线程已经启动或结束,直接抛IllegalThreadStateException异常。
- 状态转换:start0() 是一个本地方法(Native Method),由 JVM 实现,负责真正启动线程。调用 start0() 后,线程进入就绪(RUNNABLE) 状态,等待 CPU 调度。
4. 总结
通过前面的分析,相信大家已经明白了:start() 方法只能调用一次。如果尝试调用两次,程序会抛出 IllegalThreadStateException 异常。
这是因为线程的生命周期是单向的,从创建(NEW)到运行(RUNNABLE),再到终止(TERMINATED)。一旦线程开始执行,它的状态会逐步推进,最终结束,无法回退。

浙公网安备 33010602011771号