Java线程是如何创建的_常见创建方式对比总结

发布时间 - 2026-01-27 00:00:00    点击率:
推荐使用 ExecutorService + Callable 或 CompletableFuture:前者适用于需返回值和异常处理的场景,后者适合异步编排;手写 Thread 子类仅限教学或极简场景,实际项目中应重视线程池配置细节。

直接继承 Thread 类:简单但不推荐

这是最直观的创建方式,定义一个类继承 Thread,重写 run() 方法,然后调用 start() 启动。

问题在于 Java 不支持多重继承,一旦你的业务类已经继承了其他父类,这条路就走不通;而且线程逻辑和业务逻辑耦合过紧,不利于复用和测试。

  • start() 才真正启动新线程;直接调用 run() 只是普通方法执行,不会开启线程
  • 每个任务都需要新建一个子类,无法复用已有线程资源
  • 无法返回执行结果,也不方便捕获异常(异常会直接抛到 Thread 的未捕获处理器)

实现 Runnable 接口:更灵活的基础方案

把任务逻辑封装进 Runnable 实现类,再传给 Thread 构造器。这是解耦的第一步,也是最常用的起点。

它规避了继承限制,也更适合面向接口编程。但仍有局限:不能返回值、不能抛受检异常、无法获取执行状态。

Thread t = new Thread(new Runnable() {
    public void run() {
        System.out.println("Hello from Runnable");
    }
});
t.start();
  • 适合「只做一件事、不关心结果」的场景,比如日志异步刷盘、心跳上报
  • 可配合线程池使用:ExecutorService.submit(Runnable) 会忽略返回值
  • 若需返回值,必须自己加共享变量 + 同步控制,容易出错

实现 Callable + Future:需要结果时的标准解法

当任务需要返回值或可能抛出异常时,CallableRunnable 的增强替代。它用 call() 方法代替 run(),支持泛型返回值和受检异常。

Callable 不能直接交给 Thread,必须通过 ExecutorService 提交,返回 Future 对象来取结果或判断状态。

ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(() -> {
    Thread.sleep(1000);
    return "Done";
});
String result = future.get(); // 阻塞等待
executor.shutdown();
  • future.get() 默认阻塞,超时版本 get(long, TimeUnit) 更安全
  • isDone()isCancelled() 可用于轮询状态,但轮询本身有性能开销
  • 线程池关闭前务必调用 shutdown()shutdownNow(),否则 JVM 不会退出

使用 ForkJoinPool / CompletableFuture:复杂并发任务的现代选择

对于可拆分的计算密集型任务(如归并排序、树遍历),ForkJoinPool 提供工作窃取机制,比普通线程池更高效;而 CompletableFuture 则让异步编排变得声明式、可组合。

它们不是“创建线程”的底层方式,而是更高层的抽象——你不再手动管理 Thread 实例,而是描述任务依赖与执行策略。

  • CompletableFuture.supplyAsync(...) 默认使用 ForkJoinPool.commonPool(),注意其线程数固定(通常为 CPU 核数 -1),IO 密集型任务应显式传入自定义线程池
  • ForkJoinPool 中的子任务不要调用 join() 外部 ForkJoinTask,否则可能引发死锁
  • 过度使用 CompletableFuture.thenApplyAsync 而不指定线程池,容易耗尽 commonPool,拖慢整个应用
实际项目里,90% 的异步需求用 ExecutorService + CallableCompletableFuture 就够了;手写 Thread 子类几乎只出现在教学或极简嵌入式场景中。真正容易被忽略的是线程池配置

——大小、队列类型、拒绝策略,这些细节往往比“怎么创建”更能决定系统稳定性。


# java  # 处理器  # app  # jvm  # 封装  # 父类  # 子类  # 归并排序  # 继承  # 接口  # 多重继承  # 泛型  # 线程  # Thread  # 并发  # 对象  # 异步  # 返回值  # 这是  # 死锁  # 装进  # 复用  # 的是  # 也不  # 已有  # 出现在 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 潮流网站制作头像软件下载,适合母子的网名有哪些?  Laravel如何集成第三方登录_Laravel Socialite实现微信QQ微博登录  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  大同网页,大同瑞慈医院官网?  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转  微信推文制作网站有哪些,怎么做微信推文,急?  微信公众帐号开发教程之图文消息全攻略  浅述节点的创建及常见功能的实现  Swift开发中switch语句值绑定模式  如何在万网自助建站平台快速创建网站?  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  如何快速生成凡客建站的专业级图册?  如何快速搭建个人网站并优化SEO?  Laravel如何正确地在控制器和模型之间分配逻辑_Laravel代码职责分离与架构建议  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  如何在云虚拟主机上快速搭建个人网站?  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  如何快速生成高效建站系统源代码?  javascript基于原型链的继承及call和apply函数用法分析  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  如何在Windows 2008云服务器安全搭建网站?  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  如何解决hover在ie6中的兼容性问题  图册素材网站设计制作软件,图册的导出方式有几种?  详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)  高防服务器:AI智能防御DDoS攻击与数据安全保障  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  html文件怎么打开证书错误_https协议的html打开提示不安全【指南】  如何安全更换建站之星模板并保留数据?  Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】  如何在阿里云购买域名并搭建网站?  如何确保西部建站助手FTP传输的安全性?  轻松掌握MySQL函数中的last_insert_id()  Laravel中的withCount方法怎么高效统计关联模型数量  成都网站制作公司哪家好,四川省职工服务网是做什么用?  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐  Laravel如何配置.env文件管理环境变量_Laravel环境变量使用与安全管理  昵图网官网入口 昵图网素材平台官方入口  JS弹性运动实现方法分析  如何在云服务器上快速搭建个人网站?  如何用PHP快速搭建高效网站?分步指南  如何构建满足综合性能需求的优质建站方案?  laravel怎么在请求结束后执行任务(Terminable Middleware)_laravel Terminable Middleware请求结束任务执行方法  详解Android中Activity的四大启动模式实验简述  敲碗10年!Mac系列传将迎来「触控与联网」双革新