1. 继承 Thread 类
ThreadDemo01.java (启动类)
MyThread.java (实现类)

详细讲解
- 实现类 (
MyThread.java)
public class MyThread extends Thread:
- 这是最直观的方式。
MyThread 类继承了 Thread 类,它**“是” (IS-A)** 一个线程。
@Override public void run():
- 重写
Thread 类的 run() 方法。这个 run() 方法就是新线程要执行的任务代码。
System.out.println(getName() + ...):
- 因为
MyThread 就是 一个 Thread,它可以直接调用 Thread 类的方法,比如 getName()(获取线程名)。
- 启动类 (
ThreadDemo01.java)
MyThread myThread1 = new MyThread();:
- 创建了一个
MyThread 实例。myThread1 它本身就是一个线程对象。
myThread1.setName("Thread 1 -> ");:
myThread1.start();:
- 这是最关键的一步。 调用
start() 方法会通知 JVM:“请为我启动一个新的系统线程,并在这个新线程中执行 myThread1 对象的 run() 方法。”
- 注意: 如果你调用的是
myThread1.run(),那就大错特错了。那只是在 main 线程中执行了一个普通的方法调用,并不会创建新线程。
- 优点: 编码简单,最直观。
- 缺点: 不推荐使用。 Java 是单继承的,如果你的类继承了
Thread,它就不能再继承其他任何类(比如一个业务基类),这严重限制了代码的灵活性。
2. 实现 Runnable 接口
ThreadDemo02.java (启动类)
MyRun.java (实现类)

详细讲解
- 实现类 (
MyRun.java)
public class MyRun implements Runnable:
MyRun 类实现了 Runnable 接口。Runnable 的意思是“可运行的(任务)”。这表示 MyRun “是”一个任务,它不是一个线程。
@Override public void run():
- 实现
Runnable 接口中唯一的 run() 方法,定义任务内容。
Thread.currentThread().getName():
- 注意这里的区别!
MyRun 类本身没有 getName() 方法。它必须通过 Thread.currentThread() 来获取**“当前正在执行我这个 run 方法的线程是谁”**,然后再调用那个线程的 getName()。
- 启动类 (
ThreadDemo02.java)
MyRun myRun = new MyRun();:
- 创建了一个任务对象。这个
myRun 对象可以被多个线程共享。
Thread thread1 = new Thread(myRun);:
- 这是关键:解耦! 我们创建了一个
Thread 对象(工人),并通过构造函数把任务(myRun)**“注入”**了进去。
- 这种方式下,“任务”(
MyRun)和“执行任务的机制”(Thread)是分离的。
thread1.setName("Thread 1 -> ");:
thread1.start();:
- 启动“工人”,让它去执行被注入的那个
run 方法。
Thread thread2 = new Thread(myRun);:
- 注意看,您这里创建了第二个线程,但注入了同一个
myRun 实例。这就是“多个工人执行同一个任务”的模式,非常适合资源共享(但也需要注意线程安全问题)。
- 优点: 推荐使用。 避免了单继承的局限,代码更灵活(
MyRun 还可以继承别的类)。它完美地将“任务”和“线程”解耦。
- 缺点:
run() 方法没有返回值,也不能向外抛出受检异常。