Java 多线程继承 Thread 类 vs 实现 Runnable 接口一、两种创建方式1. 继承 Thread 类classMyThreadextendsThread{Overridepublicvoidrun(){System.out.println(线程运行: Thread.currentThread().getName());}}// 启动线程MyThreadtnewMyThread();t.start();2. 实现 Runnable 接口classMyRunnableimplementsRunnable{Overridepublicvoidrun(){System.out.println(线程运行: Thread.currentThread().getName());}}// 启动线程ThreadtnewThread(newMyRunnable());t.start();二、核心区别对比对比维度继承 Thread实现 Runnable类的关系IS-A 关系本身就是线程HAS-A 关系包含一个任务扩展性不能再继承其他类单继承限制可以同时继承其他类也可实现多个接口资源共享每个线程拥有独立的实例变量同一个 Runnable 实例可被多个线程共享耦合度线程与任务耦合在一起线程与任务分离符合解耦原则代码复用每次需要创建新类同一个 Runnable 可被线程池、Executor 等复用面向对象设计偏向过程化更符合面向对象设计原则三、详细分析3.1 单继承限制最关键区别Java 不支持多继承如果类已经继承了 Thread就无法再继承其他类// ❌ 不可行如果业务需要继承某个父类classMyTaskextendsParentClass,Thread{// 编译错误}// ✅ 可行使用 RunnableclassMyTaskextendsParentClassimplementsRunnable{Overridepublicvoidrun(){// 线程逻辑}}3.2 资源共享线程安全考量// 继承 Thread每个线程拥有独立资源副本classTicketThreadextendsThread{privateinttickets10;// 每个线程各自有 10 张票Overridepublicvoidrun(){while(tickets0){System.out.println(getName() 卖票: tickets--);}}}// 启动 3 个线程 → 共卖出 30 张票各卖各的newTicketThread().start();newTicketThread().start();newTicketThread().start();// 实现 Runnable多个线程共享同一资源classTicketRunnableimplementsRunnable{privateinttickets10;// 多线程共享这 10 张票Overridepublicvoidrun(){while(tickets0){synchronized(this){if(tickets0){System.out.println(Thread.currentThread().getName() 卖票: tickets--);}}}}}// 启动 3 个线程 → 共享同一 Runnable → 共卖出 10 张票TicketRunnablernewTicketRunnable();newThread(r).start();newThread(r).start();newThread(r).start();注意共享 Runnable 时需注意线程安全问题synchronized、Lock 等。3.3 解耦设计继承 Thread实现 Runnable线程对象 要执行的任务线程对象 ≠ 要执行的任务职责混合难以扩展职责分离Thread 负责调度Runnable 负责业务逻辑无法使用线程池/Executor天然适配线程池// Runnable 适配线程池ExecutorServiceexecutorExecutors.newFixedThreadPool(3);RunnabletasknewMyRunnable();executor.execute(task);// 复用同一个 taskexecutor.execute(task);executor.shutdown();// 继承 Thread 则无法直接复用// 每次需要 new 新的线程实例四、选择建议优先使用 Runnable当且仅当以下情况使用 Thread场景推荐方式仅需重写run()方法Runnable✅需要共享数据Runnable✅需要配合线程池/ExecutorRunnable✅需要继承其他类Runnable✅需要重写 Thread 的其他方法如interrupt()的行为定制Thread简单的独立任务无需共享状态两者均可五、JDK 8 更优选择Callable 与 Lambda5.1 Callable有返回值的任务CallableIntegertask()-{Thread.sleep(1000);return42;};FutureIntegerfutureExecutors.newSingleThreadExecutor().submit(task);Integerresultfuture.get();// 获取返回值 425.2 Lambda 表达式简化写法// 最简洁直接用 Lambda本质是实现 RunnablenewThread(()-{System.out.println(线程: Thread.currentThread().getName());}).start();六、总结方面继承 Thread实现 Runnable继承灵活性❌ 单继承受限✅ 可继承任意类资源共享❌ 需 static 变量✅ 天然支持共享解耦程度❌ 任务与线程耦合✅ 任务与线程分离线程池兼容❌ 不兼容✅ 完全兼容面向对象较差较好总结“优先使用实现 Runnable 接口”是 Java 多线程编程的最佳实践。如果需要返回值使用CallableFutureJDK 8 推荐结合 Lambda 表达式进一步简化代码。