当前位置: 首页 > news >正文

Java两种创建线程方式:继承Thread vs 实现Runnable 区别详解

前言

在Java并发开发体系中,构建线程主要存在两种经典实现途径:一是编写子类继承 Thread 父类,二是自定义类实现 Runnable 接口并交由 Thread 对象承载执行。很多初学者仅会照搬模板编写代码,却不清楚二者底层设计、适用场景与拓展性的核心差距,本文结合实操案例,从语法、设计、业务场景多角度拆解二者区别。

一、两种实现方式完整代码示例

方案1:继承Thread类生成线程

该方案的设计逻辑为:自定义类直接继承 java.lang.Thread ,重写内部 run() 方法承载线程业务逻辑,实例化自定义类后调用 start() 方法启动线程。

// 自定义线程类,继承Thread
public class ExtendThread extends Thread {
// 重写run,线程运行时执行该方法
@Override
public void run() {
for (int num = 1; num <= 8; num++) {
System.out.println("继承Thread线程,输出数字:" + num);
}
}

public static void main(String[] args) {
// 构建两个独立线程对象
ExtendThread threadOne = new ExtendThread();
ExtendThread threadTwo = new ExtendThread();
// 启动线程
threadOne.start();
threadTwo.start();
}
}
方案2:实现Runnable接口构建线程

该方案将业务任务与线程执行载体拆分,自定义类实现 Runnable 接口并重写 run() 封装业务,再把任务实例传入 Thread 构造方法,借助Thread完成线程创建与调度。

// 业务任务类,仅实现Runnable接口
public class ImplRunnable implements Runnable {
@Override
public void run() {
for (int num = 1; num <= 8; num++) {
System.out.println("实现Runnable线程,输出数字:" + num);
}
}

public static void main(String[] args) {
// 仅创建一份任务实例
ImplRunnable task = new ImplRunnable();
// 多个线程共用同一个任务对象
Thread threadOne = new Thread(task);
Thread threadTwo = new Thread(task);
threadOne.start();
threadTwo.start();
}
}
二、五大核心差异点深度对比

1. 类继承约束不同(最核心区分点)

Java语言严格遵循单类继承机制,一个类仅能拥有一个直接父类:

- 继承 Thread 方案:自定义类已经占用唯一继承名额,后续无法再继承其他业务父类,拓展性被锁死;

- 实现 Runnable 方案:接口支持多实现,类实现Runnable后,依旧可以正常继承其他父类、实现多个业务接口,不会限制类的层级拓展。

2. 多线程资源共享能力天差地别

线程开发高频场景为多个线程操作同一公共资源(车票、库存、计数器等),两种方案表现完全不同:

1. 继承Thread:每次 new 自定义线程类都会生成全新独立对象,每个对象拥有专属成员变量,线程之间无法共用数据;

2. 实现Runnable:仅需实例化一份任务对象,多个Thread传入同一个任务实例,所有线程共享任务内部成员变量,天然适配资源争抢场景。

车票售卖实操案例(Runnable共享资源):

// 车票售卖任务,多窗口共享票数
public class SaleTicketTask implements Runnable {
// 所有线程共享的车票库存
private int ticketCount = 12;

@Override
public void run() {
while (ticketCount > 0) {
System.out.println(Thread.currentThread().getName() + "售出剩余第" + ticketCount + "张车票");
ticketCount--;
}
}

public static void main(String[] args) {
SaleTicketTask ticketTask = new SaleTicketTask();
// 三个窗口共用车票任务
new Thread(ticketTask, "一号售票窗口").start();
new Thread(ticketTask, "二号售票窗口").start();
new Thread(ticketTask, "三号售票窗口").start();
}
}
若采用继承Thread方式编写售票逻辑,每新建一个窗口对象都会生成独立车票库存,无法实现多窗口统一售票。

3. 代码分层与耦合程度不一样

- Thread继承模式:线程载体、业务逻辑全部耦合在同一个类中,线程运行机制和业务代码高度绑定,后期如需更换线程执行方式,需要大规模修改业务代码;

- Runnable实现模式:遵循职责单一设计思想,Runnable只负责编写业务逻辑,Thread仅负责操作系统线程的创建、调度、生命周期管理,二者完全解耦,便于单独维护、替换。

4. 底层执行逻辑细微区分

两种方式最终都会调用底层native方法 start0() 向操作系统申请创建线程,执行入口均为 run() 方法,内部调用逻辑存在区别:

1. 继承Thread:线程本身就是任务载体,执行时直接调用自身重写的 run() ;

2. 实现Runnable:Thread内部持有Runnable成员变量,执行时判断任务不为空,调用 runnable.run() ,本质是线程代理执行外部任务。

5. 代码书写简洁度

- 继承Thread:代码行数更少,无需额外创建Thread对象,对新手入门友好;

- 实现Runnable:需要多一层任务类封装,基础代码量略多,但Java 8 Lambda表达式可大幅简化编写,无需单独定义实现类:

public class LambdaThreadDemo {
public static void main(String[] args) {
// Lambda简化Runnable写法,省去独立类定义
new Thread(() -> {
System.out.println("Lambda简化实现Runnable线程");
}).start();
}
}
三、两种实现方式优缺点汇总

继承Thread子类

优势:代码直观简短,入门学习成本低,直接实例化即可启动线程。
短板:受单继承限制拓展性差、多线程无法共享资源、业务与线程逻辑高度耦合,企业项目极少使用。

实现Runnable接口

优势:突破单继承限制、多线程共享公共资源、代码分层解耦、适配Lambda简化写法,是工业级项目标准方案。
短板:基础写法需要额外搭配Thread对象,初学阶段代码结构稍复杂。

四、实际开发选用规范

1. 业务开发、并发业务(库存、订单、多窗口任务)强制选用Runnable实现方案;

2. 仅做简单Demo演示、无拓展需求的极简测试代码,可临时使用继承Thread方式;

3. Java 8及以上版本,优先使用Lambda表达式简化Runnable代码,减少冗余类文件。

五、补充拓展

除本文两种基础方案外,Java还提供 Callable+FutureTask 实现带返回值的线程,适用于需要获取线程执行结果的场景,底层同样基于Runnable接口拓展而来,本质依旧是任务与线程分离的设计思路,侧面印证Runnable模式的设计优势。

http://www.jsqmd.com/news/1075418/

相关文章:

  • 国产大模型实战指南:从合同审查到多模态票据分析
  • AI应用方向:AI智能客服与对话AI
  • 5分钟完成FF14国际服中文汉化:开源工具完全指南
  • 傻子可懂的 Harness Engineering 入门教程 + 项目实战,一次搞懂 AI 编程工程化!
  • [Android MVVM 架构笔记] 基于 Kotlin 类委托与系统级安全扩展的全局 Loading 方案
  • 3D医学影像AI建模实战指南:小样本、高鲁棒、可部署的四类可靠路径
  • 6月26日16点直播丨CANNBot支持生成单指令多线程算子
  • OneNote迁移终极指南:三步实现95%格式保留的无损转换
  • 在 Android Kotlin 开发中,Kotlin 无法识别 Lombok 生成的 getter
  • TscanCode静态代码分析解决方案:提升C++/C/Lua代码质量的技术实践
  • 用Google ADK构建行政事务导航智能体:税务与社保场景落地实践
  • AI 建议“更新数据库后删除缓存”,为什么仍可能造成长期脏数据
  • 网络数据包分类与策略执行:FMan硬件加速配置详解
  • WinCC Advanced数据导出行列转换
  • Vue 3 后台管理系统前端骨架小案例1.0版本
  • 大模型知识蒸馏实战:从软标签对齐到认知迁移
  • LangChain作业四---Memory 综合实战:构建具备短期 + 长期记忆的聊天机器人
  • ANTM股票可视化:Plotly交互+Mplfinance专业K线实战
  • LG Ultrafine 亮度调节工具:解决Windows下显示器亮度控制的智能方案
  • FIFA 23 Live Editor终极指南:打造你的完美足球世界
  • 5大核心功能深度解析:G-Helper如何让华硕笔记本性能飙升
  • 深度解析猫抓浏览器扩展:从M3U8嗅探到加密流处理的10个核心技术
  • 负责任AI工程落地:六个可编码的实践维度
  • 10104黄大年茶思屋榜文101期 第4题 大模型上下文窗口高效无损扩容技术
  • 零基础学AI人工智能:10.3 ANN人工神经网络
  • iOS安全测试框架Needle:自动化漏洞挖掘与移动应用安全评估实战指南
  • 终极AI视频插值指南:使用Flowframes轻松提升视频帧率的完整教程
  • 小红书广告视频记录
  • 遗传算法实操避坑指南:实数编码、自适应变异与精英保留
  • 量子密码分析研究