在Java多线程编程中,继承Thread类是实现自定义线程执行逻辑的基础方式之一,其核心逻辑是重写Thread类提供的run方法,将线程需要完成的具体任务代码写入该方法中,再通过调用线程的start方法触发线程执行。

继承Thread类实现线程的基本步骤
要通过继承Thread类定义线程执行逻辑,整体流程可以分为三步,下面逐一说明:
第一步:自定义线程类继承Thread
首先需要创建一个自定义的类,让它继承自java.lang.Thread类,这个自定义类就代表了我们自己的线程类型。
第二步:重写run方法定义执行逻辑
Thread类中已经定义了run方法的空实现,我们需要在自定义线程类中重写这个方法,把线程启动后要执行的代码全部放在run方法的方法体内。
第三步:创建线程实例并调用start方法启动
注意不能直接调用run方法来启动线程,直接调用run方法只会让代码在当前主线程中同步执行,只有调用start方法才会触发JVM创建新的线程并执行run方法中的逻辑。
完整代码示例
下面是一个简单的示例,自定义线程实现每隔1秒打印一次当前线程名称和计数,总共打印5次:
// 自定义线程类,继承Thread
class MyThread extends Thread {
// 重写run方法,定义线程执行逻辑
@Override
public void run() {
// 循环打印5次
for (int i = 1; i <= 5; i++) {
System.out.println("线程名称:" + Thread.currentThread().getName() + ",当前计数:" + i);
try {
// 线程休眠1秒,模拟任务执行耗时
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
// 创建自定义线程实例
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
// 设置线程名称
thread1.setName("自定义线程A");
thread2.setName("自定义线程B");
// 调用start方法启动线程,触发run方法执行
thread1.start();
thread2.start();
// 主线程的执行逻辑
for (int i = 1; i <= 3; i++) {
System.out.println("主线程执行,计数:" + i);
}
}
}
关键注意事项
- run方法是线程的执行入口,但是不能直接调用run方法启动线程,直接调用run方法不会创建新线程,只是普通的方法调用。
- 一个Thread实例只能调用一次start方法,重复调用会抛出IllegalThreadStateException异常。
- 如果线程需要传递参数,可以在自定义线程类中定义成员变量,通过构造方法或者setter方法传入参数,再在run方法中使用这些参数。
- 继承Thread类的方式存在单继承的局限性,如果自定义类已经继承了其他类,就无法再继承Thread,这种情况下可以考虑实现Runnable接口的方式。
run方法和start方法的区别
很多开发者容易混淆这两个方法的作用,我们可以通过下面的对比明确二者的差异:
| 对比项 | start方法 | run方法 |
|---|---|---|
| 作用 | 启动新线程,JVM会自动调用该线程的run方法 | 定义线程的执行逻辑,是线程的执行入口 |
| 执行线程 | 由JVM创建的新线程执行 | 如果直接调用,由当前调用方法的线程执行 |
| 调用次数 | 一个线程实例只能调用一次 | 可以多次调用,但是多次调用不会启动新线程 |
带参数的线程自定义示例
如果线程执行逻辑需要外部传入参数,可以在自定义Thread子类中添加成员变量,示例如下:
class TaskThread extends Thread {
// 定义成员变量接收参数
private String taskName;
private int loopCount;
// 构造方法传入参数
public TaskThread(String taskName, int loopCount) {
this.taskName = taskName;
this.loopCount = loopCount;
}
@Override
public void run() {
for (int i = 0; i < loopCount; i++) {
System.out.println(taskName + " 执行第 " + (i + 1) + " 次任务");
}
}
}
public class ParamThreadTest {
public static void main(String[] args) {
TaskThread thread = new TaskThread("数据备份任务", 3);
thread.start();
}
}