news 2026/9/23 5:22:25

一次性讲清:Thread / Runnable / Callable / Worker / 线程池(Java 并发不再混乱)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一次性讲清:Thread / Runnable / Callable / Worker / 线程池(Java 并发不再混乱)

很多 Android / Java 开发者,在学习并发时都会经历一个阶段:
“代码能写,但概念越学越乱。”

Thread、Runnable、Callable、Future、Worker、线程池……
看起来都和“线程”有关,但又好像都不一样。

这篇文章的目标只有一个:

用一页认知,彻底终结 Java 并发概念混乱。

一、先给结论:只记住这三句话

如果你只想记住最核心的东西,请记住这三句:

① Thread 才是真正的线程
② Runnable / Callable 都只是“任务”
③ 线程池 = 一堆 Thread(Worker)反复执行一堆 Runnable

后面所有内容,都是这三句话的展开。

二、谁才是“真正的线程”?

✅ Thread

  • Thread才是真正被 JVM / CPU 调度的执行单元
  • start()才会创建新线程
  • run()只是线程启动后的入口方法
new Thread(() -> { System.out.println("run in new thread"); }).start();

判断标准很简单:

能不能被 CPU 调度?
能 → Thread
不能 → 不是线程

三、Runnable 到底是什么?(非常容易被误解)

Runnable ≠ 线程

class MyTask implements Runnable { @Override public void run() { System.out.println("task run"); } }

Runnable的本质是:

  • 一个任务
  • 一段可被线程执行的代码
  • 自己不会创建线程
  • 自己不会并发执行

⚠️ 注意下面这个常见误区:

Runnable r = () -> System.out.println("run"); r.run(); // 不是多线程!

这只是一个普通方法调用

四、Callable 又是什么?和 Runnable 有什么区别?

Callable 的特点

  • 有返回值
  • 可以抛出异常

Callable<Integer> c = () -> 123;

但重点是:

Callable 也不是线程,甚至不能直接交给 Thread

五、Callable 是怎么跑起来的?

关键角色:FutureTask

Callable<Integer> c = () -> 123; FutureTask<Integer> task = new FutureTask<>(c); new Thread(task).start(); System.out.println(task.get());

这里发生了什么?

  • FutureTask

实现了Runnable
同时实现了Future

  • Thread 只认识Runnable
  • Callable必须先被包装成 FutureTask

FutureTask = Runnable + 结果容器

六、Thread 和 Runnable / Callable 的真正关系

一句话总结:

Thread 决定“谁来跑”
Runnable / Callable 决定“跑什么”

角色是线程吗作用
Thread执行单元
Runnable无返回值任务
Callable有返回值任务
FutureTask任务 + 结果

七、线程池里到底发生了什么?

这是理解并发的关键一步

线程池的本质结构

线程池 ├── Worker(Thread) × N └── Runnable / FutureTask(任务)

Worker 是什么?

class Worker extends Thread { @Override public void run() { while (true) { Runnable task = takeTask(); task.run(); } } }
  • Worker 是线程
  • Worker 是常驻的
  • 一个 Worker 会执行很多个 Runnable

八、为什么 Worker.run 里又调用 Runnable.run?

因为:

  • Thread 的run():线程生命周期
  • Runnable 的run():业务逻辑
线程(Worker) └── run() ← 线程入口(只进一次) └── while(true) └── task.run() ← 业务任务(进很多次)

线程和任务被彻底解耦,这就是线程池存在的意义。

九、execute / submit 的本质区别

方法返回值本质
execute(Runnable)丢任务
submit(Runnable)FutureRunnable → FutureTask
submit(Callable)FutureCallable → FutureTask

submit 内部一定会创建 FutureTask

十、三个最常见误区(一次性清空)

❌ 误区 1:实现 Runnable 就是线程

✔ 真相:Runnable 只是任务

❌ 误区 2:run() 会开启新线程

✔ 真相:只有 start()

❌ 误区 3:Thread 实现 Callable

✔ 真相:Thread 实现的是 Runnable

十一、一句压箱底总结(建议背下来)

Thread 是线程
Runnable / Callable 是任务
Worker 是线程池里的 Thread
Callable 要靠 FutureTask 才能跑
submit 一定会返回 Future

写在最后

很多并发问题,并不是 API 不会用,
而是“线程”和“任务”的边界没想清楚

当你真正理解了:

  • 线程是有限资源
  • 任务是无限的
  • 线程必须被池化、被管理

你就已经迈入了后端 / 系统级并发思维

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 10:07:39

微信小程序uniapp-vue驾考小助手驾校

文章目录具体实现截图主要技术与实现手段系统设计与实现的思路系统设计方法java类核心代码部分展示结论源码lw获取/同行可拿货,招校园代理 &#xff1a;文章底部获取博主联系方式&#xff01;具体实现截图 本系统&#xff08;程序源码数据库调试部署讲解&#xff09;带文档1万…

作者头像 李华
网站建设 2026/9/18 13:30:41

探索二阶非线性自抗扰控制器(ADRC)

二阶非线性自抗扰控制器&#xff08;ADRC&#xff09;,用的模块搭建的&#xff0c;控制简单二阶传递函数&#xff0c;可以联合粒子群在线优化自抗扰参数&#xff08;但粒子群不包含在这里面&#xff09;。 在控制领域&#xff0c;二阶非线性自抗扰控制器&#xff08;ADRC&…

作者头像 李华
网站建设 2026/9/17 18:55:55

【RK3588开发】配置基于 VS Code + CMake 的 RK3588 交叉编译开发环境

配置基于 VS Code CMake 的 RK3588 交叉编译开发环境 &#xff08;1&#xff09;安装cmake工具&#xff08;2&#xff09;编写 CMake 交叉编译配置文件 (toolchain.cmake) 这段 CMake 配置代码的目的是为了告诉 CMake 如何进行交叉编译 set(CMAKE_SYSTEM_NAME Linux) set(CMAK…

作者头像 李华
网站建设 2026/8/29 7:08:05

机器学习——罗辑回归

一、逻辑回归概念点 1.1 逻辑回归优缺点 逻辑回归&#xff08;Logistic Regression&#xff09;是一种广泛使用的统计分析方法和机器学习算法&#xff0c;主要用于处理二分类问题&#xff08;即因变量为二元类别&#xff0c;如0和1、是和否等&#xff09;。尽管名字中有“回…

作者头像 李华