在Java中,Callable
、Runnable
和FutureTask
是用于处理并发任务的关键接口和类。这些工具允许你在多线程环境中执行任务,并获取任务的结果或处理任务的异常。
1. Runnable
接口
Runnable
接口是更简单的接口,仅定义了一个run
方法,不返回结果,也不抛出受检异常。
public class MyRunnable implements Runnable {
@Override
public void run() {
try {
// 模拟耗时任务
Thread.sleep(2000);
System.out.println("Runnable task completed");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
2. Callable
接口
Callable
接口类似于Runnable
,但它可以返回一个结果并且可以抛出一个受检异常。
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
// 模拟耗时任务
Thread.sleep(2000);
return 123;
}
}
3. FutureTask
类
FutureTask
类实现了RunnableFuture
接口,- 该接口扩展了
Runnable
和Future
。FutureTask
可以包装一个Callable
或Runnable
对象,并且可以在线程中执行它们。
使用Callable
和FutureTask
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallableFutureTaskExample {
public static void main(String[] args) {
// 创建一个Callable对象
Callable<Integer> callable = new MyCallable();
// 使用Callable创建一个FutureTask
FutureTask<Integer> futureTask = new FutureTask<>(callable);
// 创建并启动一个线程来执行FutureTask
Thread thread = new Thread(futureTask);
thread.start();
try {
// 获取任务的结果
Integer result = futureTask.get();
System.out.println("Callable task result: " + result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Runnable
和FutureTask
import java.util.concurrent.FutureTask;
public class RunnableFutureTaskExample {
public static void main(String[] args) {
// 创建一个Runnable对象
Runnable runnable = new MyRunnable();
// 使用Runnable创建一个FutureTask
FutureTask<Void> futureTask = new FutureTask<>(runnable, null);
// 创建并启动一个线程来执行FutureTask
Thread thread = new Thread(futureTask);
thread.start();
try {
// 等待任务完成
futureTask.get();
System.out.println("Runnable task completed");
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结
Callable
:适用于需要返回结果或抛出受检异常的任务。Runnable
:适用于不需要返回结果或抛出受检异常的任务。FutureTask
:用于包装Callable
或Runnable
,并可以在独立线程中执行它们,还可以获取任务的执行结果或等待任务完成。get()方法会阻塞线程。