【多线程】什么时候必须/推荐使用Thread类

【多线程】什么时候必须/推荐使用Thread类

文章目录

  • 【多线程】什么时候必须/推荐使用Thread类
  • 1-什么时候必须/推荐使用Thread类
  • [什么时候必须/推荐使用 `Thread` 类?](#什么时候必须/推荐使用 Thread 类?)
    • [一、必须使用 Thread 的场景](#一、必须使用 Thread 的场景)
      • [1. 需要重写 Thread 的非 run 方法](#1. 需要重写 Thread 的非 run 方法)
      • [2. 需要自定义线程属性/行为(增强型线程)](#2. 需要自定义线程属性/行为(增强型线程))
      • [3. 线程池内部实现(Worker 线程)](#3. 线程池内部实现(Worker 线程))
    • [二、推荐使用 Thread 的场景](#二、推荐使用 Thread 的场景)
    • 三、对比总结
    • 四、实战建议

1-什么时候必须/推荐使用Thread类

java 复制代码
public class Main {
    public static void main(String[] args) {
        new MyThread().start();
    }
}
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行中: " + Thread.currentThread().getName());
    }
}

实现 Runnable 接⼝(解耦任务与线程)可以将任务剥离出来,配合 Lambda 表达式更简洁,⽀持多线程共享⼀份数据,那我们在什么场景下必须使用或者推荐使用Thread

什么时候必须/推荐使用 Thread 类?

虽然 Runnable + 线程池是现代 Java 并发的主流,但以下场景下直接操作 Thread 更合适:

一、必须使用 Thread 的场景

1. 需要重写 Thread 的非 run 方法

当需要自定义线程的异常处理、中断响应、状态监控时:

java 复制代码
class MonitoredThread extends Thread {
    @Override
    public void run() {
        System.out.println("业务逻辑");
    }
    
    @Override  // 必须继承才能重写
    public void interrupt() {
        System.out.println("线程被中断,执行清理...");
        super.interrupt();
    }
}

2. 需要自定义线程属性/行为(增强型线程)

把线程本身当作一个可复用的、带状态的实体:

java 复制代码
class CounterThread extends Thread {
    private int count = 0;
    
    @Override
    public void run() {
        while (!isInterrupted()) {
            count++;
            System.out.println(getName() + ": " + count);
        }
    }
    
    public int getCount() { return count; }  // 线程自带查询接口
}

// 使用
CounterThread t = new CounterThread();
t.setName("统计线程");
t.setDaemon(true);  // 直接控制
t.start();

3. 线程池内部实现(Worker 线程)

ThreadPoolExecutor 的 Worker 类就是继承 Thread 的,因为它需要既是任务又是线程:

java 复制代码
// 模拟线程池的 Worker
class Worker extends Thread {
    private Runnable task;
    
    Worker(Runnable task) { this.task = task; }
    
    @Override
    public void run() {
        while (task != null) {
            task.run();
            task = getNextTask(); // 复用线程取新任务
        }
    }
}

二、推荐使用 Thread 的场景

场景 为什么用 Thread 代码示例
快速原型/临时脚本 简单直接,无需线程池 new Thread(() -> {...}).start()
后台守护线程 需要 setDaemon(true) 显式控制 日志刷盘、心跳检测
精确控制线程优先级 setPriority() 必须在 start 前调用 实时性要求高的任务
线程状态监控 需要 getState(), isAlive() 运维监控、调试诊断
线程名/线程组管理 构造函数直接设置 大规模线程排查问题

三、对比总结

复制代码
┌─────────────────┬──────────────────────┬─────────────────────────────┐
│     维度        │    extends Thread    │      implements Runnable     │
├─────────────────┼──────────────────────┼─────────────────────────────┤
│ 设计意图        │ "线程是一个对象"      │ "线程执行一个任务"            │
│ 代码耦合        │ 任务+线程绑定         │ 任务与线程解耦                │
│ 资源共享        │ 单实例无法共享         │ 多线程共享同一个 Runnable      │
│ 扩展性          │ 浪费单继承位          │ 可再继承其他类                │
│ 控制能力        │ 强(生命周期/属性)    │ 弱(需借助 Thread 对象)      │
│ 适用场景        │ 框架开发、线程增强     │ 业务开发、线程池              │
└─────────────────┴──────────────────────┴─────────────────────────────┘

四、实战建议

java 复制代码
// ❌ 业务代码不推荐:功能单一,还浪费继承位
class MyThread extends Thread {
    @Override public void run() { ... }
}

// ✅ 业务代码推荐:解耦、可共享、可进线程池
class MyTask implements Runnable {
    @Override public void run() { ... }
}

// ✅ 框架/工具代码推荐:需要增强线程能力
class NamedDaemonThread extends Thread {
    public NamedDaemonThread(String name, Runnable r) {
        super(r, name);
        setDaemon(true);
    }
}

一句话结论 :写业务逻辑用 Runnable + 线程池;写框架、工具类或需要把线程本身当作一个可管理的资源对象 时,继承 Thread。


相关推荐
1024奇点7 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch8 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
天河归来8 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
Knight_AL8 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing039 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by209999 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河10 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
IT召唤狮10 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻10 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble10 小时前
C++ 用互斥锁实现读写锁
开发语言·c++