在 Java 多线程入门学习中,继承 Thread 类、实现 Runnable 接口是两种最基础的线程创建方式,日常开发经常用到,很多初学者分不清两者区别与使用场景,本文从代码、继承特性、资源共享、设计思想几个方面对比梳理。

一、两种方式代码示例

1、继承 Thread 类创建线程

自定义类继承 Thread,重写 run () 方法,实例化对象调用 start () 启动线程。

java

运行

class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(getName() + ":" + i);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.setName("线程1");
        t.start();
    }
}

2、实现 Runnable 接口创建线程

自定义类实现 Runnable 接口,重写 run (),将任务对象传入 Thread 构造方法,调用 start () 开启线程。

java

运行

class MyTask implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}
public class Test {
    public static void main(String[] args) {
        MyTask task = new MyTask();
        Thread t1 = new Thread(task, "线程A");
        Thread t2 = new Thread(task, "线程B");
        t1.start();
        t2.start();
    }
}

二、核心区别

  1. 继承限制 继承 Thread:Java 单继承机制,继承 Thread 后无法再继承其他父类,类拓展性差。 实现 Runnable:接口可以多实现,实现 Runnable 之后,类还能继承其他父类、实现其他接口,没有单继承约束。

  2. 资源共享 继承 Thread:每次 new 子类都是独立对象,成员变量各自独立,很难实现多线程共用同一份数据。 实现 Runnable:多个 Thread 线程可以共用同一个 Runnable 任务对象,天然支持多线程资源共享,适合售票、抢资源等场景。

  3. 设计职责 继承 Thread:线程对象和业务任务耦合在同一个类中,违背单一职责原则,Thread 既负责线程调度又承载任务。 实现 Runnable:任务和线程解耦,Runnable 只封装业务逻辑,Thread 只负责创建、启动线程,代码分层清晰。

三、使用场景总结

  1. 优先选择实现 Runnable:需要共享资源、已有父类要继承、配合线程池开发(线程池接收参数为 Runnable),企业项目绝大多数场景使用。
  2. 选用继承 Thread:任务简单独立、不需要数据共享、小型简易测试代码。

补充知识点

  1. Thread 类底层本身实现了 Runnable 接口,两种方式最终都是重写 run () 存放线程任务。
  2. start () 方法用来向操作系统申请创建新线程,自动执行 run ();直接调用 run () 只是普通方法调用,不会开启新线程。
  3. JDK8 及以上可以用 Lambda 表达式简写 Runnable,简化代码书写:new Thread (()-> System.out.println ("线程任务")).start ();

更多推荐