奇葩面试题:线程调用两次start方法会怎样?

不知道小伙伴们在面试的时候,有没有被面试官问过这一道面试题:同一个线程调用两次start方法会怎样?

可能小伙伴们都觉得这问题多少有点毛病,谁会没事去调用两次start?

既然问都问了,我们直接去跑一下代码看看是什么情况:

大家都可以看到了,第二次调用start的时候,抛出了java.lang.IllegalThreadStateException异常。

在java中,Thread类的start方法是用于启动一个新线程的,我们去看看start方法内部的源码:

java 复制代码
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异常。而这个threadStatus变量为线程的状态变量。

group.add(this) 方法是将当前线程添加到线程组中。线程组用于管理一组线程,可以对其进行批量操作(如中断所有线程)。而 start0 是一个 native 方法用于启动线程。

java 复制代码
private native void start0();

因此当我们第一次调用 start 方法时,线程进入就绪(Runnable)状态,并等待线程调度器分配 CPU 时间片来执行其 run 方法。

java 复制代码
public enum State {
	//线程对象已创建,但尚未启动
    NEW,
	//线程正在运行或准备运行
    RUNNABLE,
	//线程被阻塞,等待监视器锁
    BLOCKED,
	//线程等待另一个线程执行特定操作
    WAITING,
	//线程等待指定时间
    TIMED_WAITING,
	//线程等待指定时间
    TERMINATED;
}

Thread类的内部是有一个名为State的枚举类的,它明确定义了一个线程的生命周期都有哪些状态。

当一个线程从 NEW 状态变为 RUNNABLE 状态后,它的生命周期已经开始了,直到它进入 TERMINATED 状态。线程生命周期的管理需要确保线程状态的一致性。

相关推荐
ym hyd 1113 小时前
试题库管理系统源码 Java+SpringBoot+Vue3 前后分离
java·vue.js·spring boot·毕设
AC赳赳老秦3 小时前
采集行为合规自检:OpenClaw 自动校验 robots 协议与采集频率,规避违规采集风险
java·开发语言·c++·python·php·deepseek·openclaw
钱栈up3 小时前
mvn compile 卡死在 javac 阶段:一次类型不匹配的排查与修复
java·开发语言
吠品5 小时前
CSS图片模糊过渡:一个transition加filter就够
java·数据库·notepad++
步行cgn5 小时前
Spring 全注解开发详解
java·后端·spring
长河6 小时前
Java的GC(垃圾回收)中,标记无用对象的核心方法是可达性分析算法
java·jvm·算法
code2cat6 小时前
Java进阶篇之LongAdder:把统计更新分散,再读取总和
java·并发编程·原子类·longadder
凯哥Java6 小时前
写代码怎么避免逻辑漏洞?
java·开发语言·人工智能·自动化
Ivanqhz6 小时前
正余弦位置编码(Sinusoidal Positional Encoding)
java·linux·数据库
BD_Marathon7 小时前
消息对象中字段的说明
java·前端·python