奇葩面试题:线程调用两次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 状态。线程生命周期的管理需要确保线程状态的一致性。

相关推荐
大象席地抽烟9 小时前
使用 Ollama 本地模型与 Spring AI Alibaba
后端
程序员小假9 小时前
SQL 语句左连接右连接内连接如何使用,区别是什么?
java·后端
小坏讲微服务9 小时前
Spring Cloud Alibaba Gateway 集成 Redis 限流的完整配置
数据库·redis·分布式·后端·spring cloud·架构·gateway
怕什么真理无穷9 小时前
C++_面试题_21_字符串操作
java·开发语言·c++
Lxinccode9 小时前
docker(25) : 银河麒麟 V10离线安装docker
java·docker·eureka·银河麒麟安装docker·银河麒麟安装compose
遇见火星9 小时前
LINUX的 jq命令行处理json字段指南
java·linux·json·jq
高山上有一只小老虎9 小时前
等差数列前n项的和
java·算法
方圆想当图灵9 小时前
Nacos 源码深度畅游:Nacos 配置同步详解(下)
分布式·后端·github
rockmelodies9 小时前
东方通安装
java
方圆想当图灵10 小时前
Nacos 源码深度畅游:Nacos 配置同步详解(上)
分布式·后端·github