面试题答案
一键面试主要区别
- Future接口:
- Future是Java早期用于异步计算结果获取的接口。它只能通过
get()
方法阻塞等待任务完成来获取结果,或者通过isDone()
方法轮询任务是否完成,缺乏对异步任务完成后的链式操作支持。 - 对于多个异步任务之间存在依赖关系的场景,Future实现起来比较繁琐,需要手动管理线程间的协作。
- Future是Java早期用于异步计算结果获取的接口。它只能通过
- CompletableFuture:
- CompletableFuture是Java 8引入的,它扩展了Future接口。它支持异步任务完成后的链式调用,如
thenApply
、thenCompose
等方法,方便处理任务间的依赖关系。 - 可以通过回调机制,在任务完成时自动触发后续操作,无需阻塞等待。
- CompletableFuture是Java 8引入的,它扩展了Future接口。它支持异步任务完成后的链式调用,如
使用示例
Future接口实现
假设我们有两个异步任务,任务B依赖任务A的结果。
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> futureA = executor.submit(() -> {
// 模拟任务A执行
Thread.sleep(2000);
return 10;
});
Future<Integer> futureB = executor.submit(() -> {
try {
// 等待任务A完成并获取结果
int resultA = futureA.get();
// 模拟任务B依赖任务A的结果进行计算
Thread.sleep(2000);
return resultA * 2;
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
return -1;
}
});
try {
System.out.println("任务B的结果: " + futureB.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
executor.shutdown();
}
}
CompletableFuture实现
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> {
// 模拟任务A执行
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 10;
});
CompletableFuture<Integer> futureB = futureA.thenApplyAsync(resultA -> {
// 模拟任务B依赖任务A的结果进行计算
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return resultA * 2;
});
futureB.thenAccept(System.out::println).join();
}
}
在上述CompletableFuture示例中,thenApplyAsync
方法实现了任务B依赖任务A结果的链式操作,并且无需显式地阻塞等待任务A完成。而在Future示例中,需要手动通过get()
方法获取任务A的结果,然后再提交任务B。