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:需要结果时的标准解法
当任务需要返回值或可能抛出异常时,Callable 是 Runnable 的增强替代。它用 call() 方法代替 run(),支持泛型返回值和受检异常。
但 Callable 不能直接交给 Thread,必须通过 ExecutorService 提交,返回 Future 对象来取结果或判断状态。
ExecutorService executor = Executors.newSingleThreadExecutor(); Futurefuture = 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,拖慢整个应用
ExecutorService + Callable 或 CompletableFuture 就够了;手写 Thread 子类几乎只出现在教学或极简嵌入式场景中。真正容易被忽略的是线程池配置
# java
# 处理器
# app
# jvm
# 封装
# 父类
# 子类
# 归并排序
# 继承
# 接口
# 多重继承
# 泛型
# 线程
# Thread
# 并发
# 对象
# 异步
# 返回值
# 这是
# 死锁
# 装进
# 复用
# 的是
# 也不
# 已有
# 出现在
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何自定义建站之星网站的导航菜单样式?
七夕网站制作视频,七夕大促活动怎么报名?
详解CentOS6.5 安装 MySQL5.1.71的方法
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
Laravel如何使用Eloquent ORM进行数据库操作?(CRUD示例)
如何为不同团队 ID 动态生成多个“认领值班”按钮
CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】
Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比
北京网站制作公司哪家好一点,北京租房网站有哪些?
高防服务器租用如何选择配置与防御等级?
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
在centOS 7安装mysql 5.7的详细教程
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
简单实现Android验证码
Laravel观察者模式如何使用_Laravel Model Observer配置
如何在阿里云完成域名注册与建站?
Laravel如何使用withoutEvents方法临时禁用模型事件
Laravel如何实现邮箱地址验证功能_Laravel邮件验证流程与配置
Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】
Android仿QQ列表左滑删除操作
如何在阿里云ECS服务器部署织梦CMS网站?
深入理解Android中的xmlns:tools属性
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
WEB开发之注册页面验证码倒计时代码的实现
Laravel如何使用Vite进行前端资源打包?(配置示例)
Laravel Seeder怎么填充数据_Laravel数据库填充器的使用方法与技巧
Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
浅述节点的创建及常见功能的实现
Python面向对象测试方法_mock解析【教程】
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
浅谈javascript alert和confirm的美化
Laravel如何使用Service Container和依赖注入?(代码示例)
微信小程序 HTTPS报错整理常见问题及解决方案
如何用美橙互联一键搭建多站合一网站?
Laravel怎么在Blade中安全地输出原始HTML内容
个人网站制作流程图片大全,个人网站如何注销?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?
Laravel如何实现RSS订阅源功能_Laravel动态生成网站XML格式订阅内容【教程】
如何快速登录WAP自助建站平台?
Laravel如何实现API速率限制?(Rate Limiting教程)
Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程
Laravel的契約(Contracts)是什么_深入理解Laravel Contracts与依赖倒置
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】
Android okhttputils现在进度显示实例代码

