如何创建线程
Java 中创建线程主要有以下四种方式:
1. 继承 Thread
类:重写 run()
方法。
2. 实现 Runnable
接口:定义 run()
,传入 Thread
。
3. 实现 Callable
接口:带返回值,用 FutureTask
配合 Thread
。
4. 线程池:通过 ExecutorService
创建和管理线程。
1. 创建线程的方式详解
(1) 继承 Thread
类
- 步骤:
- 继承
Thread
,重写run()
。 - 创建实例,调用
start()
。 - 示例:
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread running: " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
- 特点:
- 简单,但不能再继承其他类。
(2) 实现 Runnable
接口
- 步骤:
- 实现
Runnable
,定义run()
。 - 传入
Thread
构造器,调用start()
。 - 示例:
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("Runnable running: " + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
- 特点:
- 灵活,可继承其他类,推荐使用。
(3) 实现 Callable
接口
- 步骤:
- 实现
Callable
,定义call()
(带返回值)。 - 用
FutureTask
包装,传入Thread
。 - 示例:
class MyCallable implements Callable<String> {
@Override
public String call() {
return "Result from Callable: " + Thread.currentThread().getName();
}
}
public static void main(String[] args) throws Exception {
FutureTask<String> task = new FutureTask<>(new MyCallable());
Thread thread = new Thread(task);
thread.start();
System.out.println(task.get()); // 获取结果
}
- 特点:
- 支持返回值和异常,需配合
Future
。
(4) 线程池
- 步骤:
- 使用
ExecutorService
创建线程池。 - 提交
Runnable
或Callable
任务。 - 示例:
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> {
System.out.println("Thread pool: " + Thread.currentThread().getName());
});
executor.shutdown();
- 特点:
- 复用线程,高效管理,高并发首选。
2. 对比
方式 | 优点 | 缺点 | 场景 |
---|---|---|---|
Thread |
简单直接 | 不可再继承 | 简单任务 |
Runnable |
灵活,解耦 | 无返回值 | 通用任务 |
Callable |
支持返回值和异常 | 实现稍复杂 | 需结果的任务 |
线程池 | 高效,资源可控 | 配置和管理复杂 | 高并发、生产环境 |
3. 注意事项
(1) start() vs run()
start()
:- 启动新线程,调用
run()
。 run()
:- 直接调用,仅当前线程执行,无新线程。
MyThread t = new MyThread();
t.run(); // 主线程执行
t.start(); // 新线程执行
(2) 线程状态
- 创建后:
NEW
。 start()
后:RUNNABLE
。- 执行完:
TERMINATED
。
(3) 异常处理
- 未捕获异常终止线程。
- 用
Thread.setUncaughtExceptionHandler
处理。
4. 延伸与面试角度
- 原理:
Thread.start()
调用 JVM 的本地方法start0()
,创建 OS 线程。- 与进程区别:
- 线程是进程内的执行单元,共享内存。
- 实际应用:
Runnable
:任务调度。- 线程池:Web 服务器(如 Tomcat)。
- 面试点:
- 问“方式”时,提四种及代码。
- 问“选择”时,提线程池优势。
总结
Java 创建线程可通过继承 Thread
、实现 Runnable
或 Callable
,以及线程池实现。Runnable
灵活,线程池高效,依场景选择。面试时,可写简单代码或提并发场景,展示理解深度。