面试题答案
一键面试以下是Java 8中使用CompletableFuture实现该需求的代码示例:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class FutureChainingExample {
public static CompletableFuture<String> step1() {
return CompletableFuture.supplyAsync(() -> {
// 模拟异步操作
return "result from step1";
});
}
public static CompletableFuture<Integer> step2(String result1) {
return CompletableFuture.supplyAsync(() -> {
// 这里简单模拟可能失败的操作,比如根据result1判断
if ("error condition".equals(result1)) {
throw new RuntimeException("step2 failed");
}
return result1.length();
});
}
public static CompletableFuture<Double> step3(Integer result2) {
return CompletableFuture.supplyAsync(() -> {
// 基于result2进行操作
return result2.doubleValue() * 2.0;
});
}
public static CompletableFuture<Double> step3WithError(String errorMessage) {
return CompletableFuture.supplyAsync(() -> {
// 根据错误信息进行不同处理
System.out.println("Handling error in step3: " + errorMessage);
return -1.0;
});
}
public static void main(String[] args) {
step1()
.thenComposeAsync(result1 -> step2(result1)
.exceptionally(ex -> {
System.out.println("Caught error in step2: " + ex.getMessage());
return -1; // 返回一个特殊值表示错误
})
.thenComposeAsync(result2 -> {
if (result2 == -1) {
return step3WithError("step2 failed");
} else {
return step3(result2);
}
}))
.thenAcceptAsync(result3 -> System.out.println("Final result: " + result3))
.exceptionally(ex -> {
System.out.println("Final error: " + ex.getMessage());
return null;
});
// 防止主线程退出
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
在上述代码中:
step1
、step2
和step3
模拟了异步操作。- 在
step2
中,通过判断条件抛出异常模拟操作失败。 - 在
step1
的thenComposeAsync
调用中,对step2
的异常进行捕获,通过exceptionally
方法返回一个特殊值-1
表示错误。 - 在后续的
thenComposeAsync
中,根据step2
的结果判断是否为错误,如果是则调用step3WithError
方法,并将错误信息传递进去,否则调用正常的step3
方法。 - 最后通过
thenAcceptAsync
处理最终结果,exceptionally
处理整个链式调用中的最终错误。
注意,在 main
方法中,通过 Thread.sleep
防止主线程提前退出。实际应用中可能不需要这样做,这取决于具体的应用场景和线程管理方式。