Java中创建线程的主流方式是实现Runnable接口,核心三步:定义任务(实现run())、包装成Thread对象、调用start()启动;它解耦任务与执行者,避免单继承限制,支持多线程复用及线程池兼容。

Java 中通过实现接口创建线程,主流方式是实现 Runnable 接口,这是最推荐、最常用的做法。它把“任务”和“执行者”分离,避免了单继承限制,也更符合面向对象设计原则。
实现 Runnable 接口的三步写法
核心就是:定义任务 → 包装成线程 → 启动执行。
-
第一步:写一个类,实现 Runnable 接口,并重写 run() 方法
run() 里放你要在线程中执行的逻辑,比如循环打印、计算、IO 操作等。 -
第二步:用这个类的对象创建 Thread 实例
把 Runnable 实现类的对象传给 Thread 构造器,例如new Thread(myRunnable),也可以指定线程名:new Thread(myRunnable, "Worker-1")。 -
第三步:调用 start() 方法启动线程
注意不是直接调用 run() —— 那只是普通方法调用,在当前线程串行执行;start() 才会真正创建新线程并由 JVM 调度并发运行。
为什么不用继承 Thread 类,而选 Runnable?
关键在于解耦和复用:
- Java 不支持多继承,如果类已继承其他父类(比如 Service 或 Entity),就无法再继承 Thread;但可以同时实现多个接口,包括 Runnable。
- 同一个 Runnable 实例可被多个 Thread 对象使用,适合共享任务场景(如多个线程处理同一队列)。
- 后续升级到线程池时,Runnable 是 ExecutorService.submit() 的标准入参,天然兼容。
一个完整可运行的例子
下面代码创建两个线程,共用同一个 Runnable 任务:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
立即学习“Java免费学习笔记(深入)”;
(复制到 IDE 即可运行)class PrintTask implements Runnable {
private final String prefix;
<pre class="brush:php;toolbar:false;">public PrintTask(String prefix) {
this.prefix = prefix;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(prefix + " - " + i);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}}
public class RunnableDemo { public static void main(String[] args) { PrintTask task = new PrintTask("【线程A】"); Thread t1 = new Thread(task, "A"); Thread t2 = new Thread(task, "B"); // 复用同一个 task
t1.start();
t2.start();
}}
进阶:想让线程有返回值?用 Callable
Runnable 的 run() 方法没有返回值、也不能抛受检异常。如果需要结果或异常传播,可改用 Callable
- 实现 call() 方法,返回类型由泛型指定(如
Callable<integer></integer>)。 - call() 可以 throw Exception,比 run() 更灵活。
- 必须配合 FutureTask 或线程池使用,因为 Thread 构造器不直接接受 Callable;FutureTask 是 Runnable 的子类,能桥接 Callable 和 Thread。

















