Java 多线程:继承 Thread 与实现 Runnable 两种创建方式完整对比
一、前言
本文为 Java 多线程课程作业,对比两种基础线程创建方式:继承 Thread 子类、实现 Runnable 接口。分别给出完整可运行代码,从代码结构、类继承限制、资源共享、扩展性等维度分析核心区别,总结开发中推荐使用 Runnable 的原因。
二、两种创建方式代码实现(包名 com.javablog)
方式 1:继承 Thread 类创建线程
package com.javablog; // 自定义类继承Thread,重写run方法 public class MyThread extends Thread { // 共享票数 private int ticket = 10; @Override public void run() { while (ticket > 0) { System.out.println(Thread.currentThread().getName() + " 卖出第" + ticket + "张票"); ticket--; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { // 创建多个线程对象,每个对象拥有独立ticket变量 MyThread t1 = new MyThread(); MyThread t2 = new MyThread(); t1.setName("窗口1"); t2.setName("窗口2"); t1.start(); t2.start(); } }运行现象:两个窗口各自售卖 10 张票,总票数 20 张,无法共享资源。
方式 2:实现 Runnable 接口创建线程
package com.javablog; // 实现Runnable接口,重写run方法 public class MyRunnable implements Runnable { // 共享票数,所有线程共用这一个变量 private int ticket = 10; @Override public void run() { while (ticket > 0) { System.out.println(Thread.currentThread().getName() + " 卖出第" + ticket + "张票"); ticket--; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) { // 只创建一份任务对象 MyRunnable task = new MyRunnable(); // 多个Thread共用同一个任务,共享ticket资源 Thread t1 = new Thread(task, "窗口1"); Thread t2 = new Thread(task, "窗口2"); t1.start(); t2.start(); } }运行现象:两个窗口共同售卖 10 张票,多线程共享同一份资源。
三、核心区别对比
| 对比维度 | 继承 Thread 子类 | 实现 Runnable 接口 |
| 继承限制 | Java 是单继承,继承 Thread 后无法再继承其他父类,扩展性差 | 仅实现接口,不占用类继承名额,可同时继承其他类,扩展性强 |
| 资源共享 | 每个线程对象独立,成员变量互不共享,多线程操作同一资源需要静态变量 | 多个 Thread 可共用同一个 Runnable 任务对象,天然共享成员变量,适合售票、抢单等场景 |
| 职责分离 | 线程对象与业务逻辑耦合在一起,线程控制、业务代码写在同一个类 | 解耦:Thread 只负责线程调度,Runnable 仅存放业务执行逻辑,符合单一职责 |
| 代码复用 | 业务逻辑绑定线程类,复用性弱 | 任务可重复交给多个线程、线程池执行,复用性高 |
| 开发推荐度 | 仅简单一次性测试场景使用 | 项目、竞赛标准首选方案 |
四、关键细节解析
1.单继承限制(最核心短板)
Java 不支持多类继承,如果业务类已经继承其他父类,就不能再继承 Thread;而 Runnable 是接口,一个类可以实现多个接口,无继承冲突。
2.资源共享差异原理
继承 Thread:每次new MyThread()都会新建对象,成员变量是实例私有;
实现 Runnable:只创建一个任务实例,传入多个 Thread,所有线程操作同一个对象的成员变量,天然共享数据。
3.解耦设计思想
Thread 类是 JVM 提供的线程调度器,负责开启、休眠、中断线程;Runnable 只承载需要执行的业务代码,将「线程调度」和「业务逻辑」分开,代码更清晰。
五、运行结果示例
继承 Thread 输出(不共享票)
实现 Runnable 输出(共享票)
六、总结
1.继承 Thread 类:写法简单,但受 Java 单继承限制,无法共享实例资源,扩展性差,仅适合简单测试;
2.实现 Runnable 接口:无继承限制、天然支持多线程资源共享、职责解耦、任务可复用,是企业开发、竞赛通用标准写法;
3.实际开发中,一律优先选择实现 Runnable 接口的方式创建线程。