必须重写 Thread 类的 run() 方法来定义线程任务逻辑,且需用 @Override 注解、void 返回类型、无参数、不抛受检异常;调用 start() 才启动新线程,直接调用 run() 仅同步执行。

在 Java 中,通过继承 Thread 类来创建线程时,必须重写其 run() 方法,因为该方法定义了线程要执行的任务逻辑。直接调用 run() 不会启动新线程,只有调用 start() 才会真正开启线程并自动执行 run() 中的代码。
重写 run() 的基本写法
继承 Thread 类后,用 @Override 注解明确重写 run(),方法签名必须严格匹配:返回类型为 void,无参数,且不能抛出受检异常(除非在内部处理)。
- 不要在
run()中调用start(),否则会抛出IllegalThreadStateException - 避免在
run()中使用System.exit()或长时间阻塞未响应的操作,影响线程生命周期管理 - 若需传入数据,可通过构造方法将参数保存为成员变量,在
run()中使用
一个典型示例
下面是一个打印 5 次线程名称的自定义线程类:
class MyThread extends Thread {
private String message;
<pre class="brush:php;toolbar:false;">public MyThread(String message) {
this.message = message;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(message + " - " + i + " (Thread: " + getName() + ")");
try {
Thread.sleep(100); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 恢复中断状态
return;
}
}
}}
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
立即学习“Java免费学习笔记(深入)”;
// 使用方式: public class Main { public static void main(String[] args) { MyThread t1 = new MyThread("Task-A"); MyThread t2 = new MyThread("Task-B"); t1.start(); // 启动线程,触发 run() t2.start(); } }
注意事项与常见误区
重写 run() 时容易忽略的关键点:
- 不能直接调用 run():这只会像普通方法一样在当前线程中同步执行,不会并发
- 不要在 run() 中捕获并吞掉 InterruptedException:应恢复中断状态或按需退出,否则可能造成线程无法被正常中断
- 避免在 run() 中修改共享变量而不加同步:多个线程同时运行时可能引发数据竞争
- run() 结束即线程终止:JVM 会回收该线程资源,无需手动清理(但需确保业务逻辑已正确收尾)
替代方案提醒
虽然继承 Thread 类可以重写 run(),但更推荐实现 Runnable 接口或使用 Callable 配合线程池。这样能避免单继承限制,提高代码复用性,也更符合面向接口编程原则。

















