创建线程的6种方式
1. 使用 Thread
类和 Lambda 表达式
这是 Java 8 引入的一种简洁的创建线程的方式,适用于实现 Runnable
接口的线程。
new Thread(() -> {
// 线程执行的代码
}, "线程名称").start();
- **
() -> { ... }
**:Lambda 表达式,表示Runnable
接口的run()
方法。 - **
"线程名称"
**:线程的名称(可选)。 - **
start()
**:启动线程。
示例:
new Thread(() -> {
System.out.println("线程执行中...");
}, "MyThread").start();
2. 实现 Runnable
接口
这是最常用的创建线程的方式。Runnable
是一个函数式接口,只有一个 run()
方法。
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("线程执行中...");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable(), "MyThread");
thread.start();
}
}
- 优点:可以避免单继承的限制(因为 Java 不支持多继承)。
- 缺点:需要显式创建
Runnable
的实现类。
3. 继承 Thread
类
通过继承 Thread
类并重写 run()
方法来创建线程。
class MyThread extends Thread {
@Override
public void run() {
System.out.println("线程执行中...");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
- 优点:简单直接。
- 缺点:由于 Java 不支持多继承,如果继承了
Thread
类,就不能再继承其他类。
4. 使用 Callable
和 FutureTask
Callable
与 Runnable
类似,但可以返回结果并抛出异常。通常与 FutureTask
结合使用。
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<String> {
@Override
public String call() throws Exception {
return "线程执行完成";
}
}
public class Main {
public static void main(String[] args) throws Exception {
FutureTask<String> futureTask = new FutureTask<>(new MyCallable());
Thread thread = new Thread(futureTask, "MyThread");
thread.start();
// 获取线程执行结果
String result = futureTask.get();
System.out.println(result);
}
}
- 优点:可以获取线程的执行结果。
- 缺点:使用稍复杂。
5. 使用线程池(ExecutorService
)
通过线程池管理线程,避免频繁创建和销毁线程的开销。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(() -> {
System.out.println("线程 1 执行中...");
});
executor.submit(() -> {
System.out.println("线程 2 执行中...");
});
executor.shutdown();
}
}
- 优点:高效管理线程,适合并发任务。
- 缺点:需要手动管理线程池的生命周期。
6. 使用 CompletableFuture
(Java 8+)
CompletableFuture
提供了更强大的异步编程能力,可以方便地处理线程执行结果和异常。
import java.util.concurrent.CompletableFuture;
public class Main {
public static void main(String[] args) {
CompletableFuture.runAsync(() -> {
System.out.println("线程执行中...");
}).join(); // 等待线程执行完成
}
}
- 优点:支持链式调用和组合异步任务。
- 缺点:适用于复杂的异步编程场景。
总结
方式 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
Thread + Lambda | 简洁,适合简单任务 | 无法复用线程逻辑 | 简单的异步任务 |
实现 Runnable | 避免单继承限制 | 需要显式创建实现类 | 通用的线程实现 |
继承 Thread | 简单直接 | 无法继承其他类 | 简单的线程实现 |
Callable + FutureTask | 可以获取线程结果 | 使用稍复杂 | 需要返回结果的线程 |
线程池(ExecutorService ) | 高效管理线程,适合并发任务 | 需要手动管理线程池 | 并发任务 |
CompletableFuture | 强大的异步编程能力 | 适用于复杂场景,学习曲线较高 | 复杂的异步任务 |
在实际开发中,推荐优先使用 线程池 或 CompletableFuture ,因为它们更高效且功能强大。对于简单的任务,可以使用 Thread
+ Lambda 或 Runnable
。