Java 创建线程的几种方式
在 Java 中,创建线程主要有以下几种方式。下面我将详细解释每种方式,并提供代码示例。
1. 继承 Thread 类
这是最基础的创建线程方式,通过继承 Thread 类并重写 run() 方法。
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程运行中: " + Thread.currentThread().getName());
}
}
// 使用方式
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
特点:
简单直接由于 Java 是单继承,这种方式会占用继承位置线程与任务耦合在一起
2. 实现 Runnable 接口
更常用的方式是实现 Runnable 接口,将线程和任务解耦。
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程运行中: " + Thread.currentThread().getName());
}
}
// 使用方式
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
// 或者使用 Lambda 表达式(Java 8+)
Thread lambdaThread = new Thread(() -> {
System.out.println("Lambda 线程运行中: " + Thread.currentThread().getName());
});
lambdaThread.start();
}
}
特点:
推荐使用的方式线程与任务分离,更灵活可以实现多个接口,不影响类继承结构
3. 实现 Callable 接口
Callable 与 Runnable 类似,但可以返回结果和抛出异常。
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class MyCallable implements Callable
@Override
public String call() throws Exception {
Thread.sleep(1000); // 模拟耗时操作
return "任务执行完成: " + Thread.currentThread().getName();
}
}
// 使用方式
public class Main {
public static void main(String[] args) throws Exception {
FutureTask
Thread thread = new Thread(futureTask);
thread.start();
// 获取执行结果(会阻塞直到任务完成)
String result = futureTask.get();
System.out.println(result);
}
}
特点:
可以返回执行结果可以抛出异常需要配合 FutureTask 或线程池使用
4. 使用线程池(ExecutorService)
在实际开发中,最推荐使用线程池来管理线程,提高资源利用率。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
// 提交任务
for (int i = 0; i < 5; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("任务 " + taskId + " 执行中: " + Thread.currentThread().getName());
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池
executor.shutdown();
try {
// 等待所有任务完成
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
}
} catch (InterruptedException e) {
executor.shutdownNow();
}
}
}
特点:
管理和复用线程,减少创建销毁开销控制并发线程数量提供任务队列、定时执行等功能
5. 使用 CompletableFuture (Java 8+)
Java 8 引入的 CompletableFuture 提供了更强大的异步编程能力。
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建异步任务
CompletableFuture
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "异步任务结果";
});
// 处理任务结果
future.thenAccept(result -> {
System.out.println("处理结果: " + result);
});
// 等待任务完成
future.get();
}
}
6. 使用 Spring 的 @Async 注解
在 Spring 框架中,可以使用 @Async 注解轻松创建异步方法。
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@EnableAsync
@Component
public class AsyncService {
@Async
public void asyncMethod() {
System.out.println("异步方法执行: " + Thread.currentThread().getName());
}
}
// 在 Controller 或 Service 中调用
asyncService.asyncMethod();
对比总结
创建方式优点缺点适用场景继承 Thread简单直接占用继承位置,耦合度高简单测试或demo实现 Runnable灵活,解耦不能直接返回结果大多数场景实现 Callable可返回结果,可抛异常使用稍复杂需要返回结果的异步任务线程池资源复用,功能强大配置稍复杂生产环境,高并发场景CompletableFuture功能强大,链式编程Java 8+ 支持复杂异步编程Spring @Async集成简单,注解驱动需要 Spring 环境Spring 项目中的异步处理最佳实践建议
优先使用线程池而不是直接创建线程,避免资源浪费实现 Runnable 接口比继承 Thread 类更灵活需要返回值时使用 Callable 和 Future在 Spring 项目中使用 @Async 注解简化异步编程对于复杂异步流程,使用 CompletableFuture始终处理线程中的异常,避免 silent failure
// 异常处理示例
Thread thread = new Thread(() -> {
try {
// 任务代码
} catch (Exception e) {
System.err.println("线程执行异常: " + e.getMessage());
}
});
thread.setUncaughtExceptionHandler((t, e) -> {
System.err.println("线程 " + t.getName() + " 发生异常: " + e.getMessage());
});
thread.start();
根据具体需求选择合适的线程创建方式,可以提高代码的可维护性和性能。