发布于2026-07-09 阅读(0)
扫一扫,手机访问
在 Ja va 多线程编程中,启动线程的正确方式只有一个——调用 Thread 实例的 start() 方法。这可不是什么“最佳实践”,而是 Ja va 线程生命周期强制的规则。如果你直接调用 run(),那就只是调用了一个普通方法,和新建线程八竿子打不着。咱们先把这个基础说透,后面再看那些容易踩的坑。

每个线程对象只能被启动一次,这是线程状态机设计的铁律。start() 内部会先检查当前线程的状态——只有当 threadStatus 等于 0(即 NEW 状态)时,才会继续往下走;否则直接抛出 IllegalThreadStateException。换句话说,线程状态只能单向流转:新建 → 就绪 → 运行 → 终止,不能回退,也不能重复启动。
start() 后,JVM 会触发本地方法 start0(),由底层操作系统(比如 Linux 的 pthread_create 或 Windows 的 CreateThread)真正创建原生线程。Thread 对象,并在这个新线程的上下文中执行 run() 里的逻辑。start() 只是“提交请求”,并不决定什么时候执行——实际调度权在操作系统手里。run() 本质上就是一个普通的实例方法,里面放的是线程要干的具体活儿。它本身没有任何线程管理能力:
runnable.run() 或 thread.run(),代码会在当前线程(通常是主线程)同步执行,根本没有并发效果。run() 是为了定义业务逻辑,但你必须通过 start() 才能让这段逻辑在新线程里跑起来。Runnable 接口的 run() 还是 Thread 子类的 run(),语义都一样——只是任务声明,不是执行指令。虽然生产环境一般靠代码结构保证每个 Thread 只启动一次,但在调试或关键路径上,主动做一下状态检查也没什么坏处:
t.getState() == Thread.State.NEW 来判断线程尚未启动。getState() 和 start() 之间有一个极小的时间窗口,不能把它当作并发控制的手段,只适用于诊断或防御性编程。Thread 实例只被 start() 一次(比如通过标志位,或者构造时就启动)。下面这些操作都属于违规行为,应该尽量避免:
start():必然抛出 IllegalThreadStateException,程序直接中断。start():状态已经是 TERMINATED,同样非法。run() 替代 start():看着像“执行了”,其实根本没有并发,所有逻辑都串行运行在主线程上。start():比如刚 new 出来就 sleep 了,再 start——只要没被启动过,仍是合法的;但一旦 start 过,哪怕线程还没真正跑起来,状态也已经变了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8