Java 两种创建线程方式:继承 Thread 类 VS 实现 Runnable 接口全面对比 在 Java 多线程入门学习中继承 Thread 子类与实现 Runnable 接口配合 Thread是最基础的两种线程创建方案很多初学者刚接触时容易混淆两者使用场景与底层差异。本文从实现原理、代码示例、优缺点、适用场景四个维度拆解区别帮你彻底理清选型逻辑。一、两种方式代码实现演示1. 方式一继承 Thread 类创建线程原理自定义类继承java.lang.Thread重写run()方法线程任务体实例化子类对象后调用start()启动线程。java// 自定义线程类继承Thread class MyThread extends Thread { // 重写run线程执行的业务逻辑 Override public void run() { for (int i 0; i 5; i) { System.out.println(Thread.currentThread().getName() i); } } } public class ThreadDemo { public static void main(String[] args) { // 创建线程实例 MyThread t1 new MyThread(); MyThread t2 new MyThread(); // 启动线程自动执行run() t1.start(); t2.start(); } }关键start()会向 JVM 申请开启操作系统线程由 JVM 自动回调run()直接调用run()只是普通方法调用不会新建线程。2. 方式二实现 Runnable 接口创建线程原理自定义类实现Runnable接口、重写run()存放任务将 Runnable 实现类作为参数传入 Thread 构造器借助 Thread 对象start()启动线程。// 任务类实现Runnable接口只负责封装任务 class MyRunnable implements Runnable { Override public void run() { for (int i 0; i 5; i) { System.out.println(Thread.currentThread().getName() i); } } } public class RunnableDemo { public static void main(String[] args) { // 同一个任务实例 MyRunnable task new MyRunnable(); // 多个线程共用同一个任务对象 Thread t1 new Thread(task, 线程A); Thread t2 new Thread(task, 线程B); t1.start(); t2.start(); } }二、核心五大区别详解1. 继承限制不同最关键区别继承 ThreadJava 是单继承一旦类继承Thread就无法再继承其他父类继承链被锁死扩展性差。实现 Runnable接口是多实现实现Runnable后类还能正常继承别的父类、实现其他接口规避单继承局限性符合面向接口编程思想。2. 资源共享能力不同继承 Thread每次创建new MyThread()都是全新对象每个线程独占成员变量很难实现多线程共享同一份资源如需共享只能用静态变量容易引发线程安全隐患。实现 Runnable多个Thread对象可以传入同一个 Runnable 任务实例天然共享任务类中的成员变量资源共享简单便捷适合售票、抢券等多线程操作同一资源场景。示例多线程卖票Runnable 优势class TicketTask implements Runnable { private int ticket 10; // 共享票数 Override public void run() { while (ticket 0) { System.out.println(Thread.currentThread().getName()卖第ticket--张票); } } } // 三个线程共用10张票资源 Thread t1new Thread(new TicketTask(),窗口1); Thread t2new Thread(new TicketTask(),窗口2); Thread t3new Thread(new TicketTask(),窗口3);3. 职责分层不同Thread 继承线程对象 业务任务耦合在同一个类中线程创建和任务逻辑绑定不符合单一职责原则代码臃肿。Runnable 实现任务与线程分离Runnable 只封装业务任务Thread 只负责线程调度与资源创建解耦设计方便任务复用。4. 代码复用与灵活性Thread 子类任务绑定线程本身任务无法脱离线程单独复用Runnable任务是独立对象既能交给 Thread 运行也能配合线程池ExecutorService使用是线程池、Lambda 表达式底层默认规范。5. Lambda 适配JDK8Runnable 是函数式接口只有一个抽象方法 runJDK8 后可直接用 Lambda 简写代码无需单独创建实现类java运行// 一行代码创建线程 new Thread(()- System.out.println(Lambda创建Runnable线程)).start();而继承 Thread 无法使用 Lambda 简化。三、优缺点总结表格对比项继承 Thread 类实现 Runnable 接口继承约束受 Java 单继承限制不能再继承其他类无继承限制可多实现、多继承资源共享多线程资源共享麻烦依赖 static天然支持多线程共享同一个任务资源代码耦合任务和线程对象耦合单一职责差任务、线程解耦扩展性强适用场景简单独立任务、不需要资源共享的小程序绝大多数生产环境、资源共享、线程池开发Lambda 支持不支持支持 Lambda 简写1. Thread 继承优缺点✅ 优点代码写法简单直接 new 子类调用 start ❌ 缺点单继承受限、资源共享困难、耦合度高项目开发极少使用。2. Runnable 实现优缺点✅ 优点解耦、无继承限制、资源共享方便、适配线程池与 Lambda企业开发首选 ❌ 缺点代码相比继承多一层封装新手初期理解略繁琐。四、生产环境选型建议优先使用实现 Runnable 方式项目开发 95% 场景选用尤其是多线程处理同一资源、配合线程池开发时仅简单测试小 Demo 用 Thread 继承日常练习、一次性简单任务追求代码极简时临时使用补充除了两种基础方式Java 还有CallableFutureTask创建带返回值线程本质底层依然依托 Runnable 思想。五、拓展延伸源码底层逻辑Thread 类源码中存在private Runnable target;成员变量当传入 Runnable 构造时target 赋值为传入任务start()启动后 JVM 回调run()会执行target.run()继承 Thread 重写 run 时直接覆盖父类 run 方法忽略 target所以两种方式最终都是执行 run 方法只是任务来源不同。结语多线程开发中优先 Runnable是行业共识本质是面向接口、解耦编程思想的体现。掌握两者区别不仅应付面试高频考题更是后续学习线程池、并发工具的基础。