1 创建线程的方式
在 Java 中,创建线程的方式主要有以下几种:
-
继承
Thread
类:- 通过继承
Thread
类并重写run()
方法来创建线程。 - 示例代码:
class MyThread extends Thread { @Override public void run() { // 线程执行的代码 } } public class Main { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } }
- 通过继承
-
实现
Runnable
接口:- 通过实现
Runnable
接口并实现run()
方法来创建线程。 - 示例代码:
class MyRunnable implements Runnable { @Override public void run() { // 线程执行的代码 } } public class Main { public static void main(String[] args) { MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); } }
- 通过实现
-
实现
Callable
接口:- 通过实现
Callable
接口并实现call()
方法来创建线程。Callable
接口允许线程返回一个结果,并且可以抛出异常。 - 示例代码:
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { // 线程执行的代码 return 42; } } public class Main { public static void main(String[] args) throws InterruptedException, ExecutionException { MyCallable callable = new MyCallable(); FutureTask<Integer> futureTask = new FutureTask<>(callable); Thread thread = new Thread(futureTask); thread.start(); System.out.println(futureTask.get()); // 获取线程执行结果 } }
- 通过实现
-
线程池方式:
- 通过使用
ExecutorService
线程池来管理线程的创建和执行。 - 示例代码:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Main { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(new MyRunnable()); executorService.shutdown(); } }
- 通过使用
2 Callable
接口
2.1 Runnable
接口和 Callable
接口的比较
-
是否有返回值:
Runnable
接口的run()
方法没有返回值。Callable
接口的call()
方法有返回值,返回类型为泛型。
-
是否抛出异常:
Runnable
接口的run()
方法不能抛出受检异常(checked exception)。Callable
接口的call()
方法可以抛出受检异常。
-
实现方法名称不同:
Runnable
接口的实现方法是run()
。Callable
接口的实现方法是call()
。
2.2 FutureTask
概述和原理
2.2.1 概述
FutureTask
是 Future
接口的一个实现类,用于表示一个异步计算任务。它可以将 Callable
或 Runnable
任务包装成 FutureTask
,并且可以通过 FutureTask
获取任务的执行结果。
2.2.2 原理
- 状态管理:
FutureTask
内部维护了一个状态变量,用于表示任务的当前状态(如未启动、运行中、已完成、已取消等)。 - 结果存储:
FutureTask
内部存储了任务的执行结果或异常。 - 线程安全:
FutureTask
通过ReentrantLock
和Condition
实现线程安全的等待和通知机制。
2.2.3 示例代码
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 线程执行的代码
return 42;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
MyCallable callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get()); // 获取线程执行结果
}
}
3 总结
在 Java 中,创建线程的方式有多种,包括继承 Thread
类、实现 Runnable
接口、实现 Callable
接口和使用线程池。Callable
接口允许线程返回结果并抛出异常,而 FutureTask
是 Future
接口的一个实现类,用于管理异步计算任务的状态和结果。通过合理使用这些机制,可以有效地管理和控制线程的执行。