completablefuture.runAsync设定返回值
时间: 2023-11-07 17:20:37 浏览: 188
CompletableFuture.runAsync() 方法返回的是一个 CompletableFuture<Void>,也就是说该方法没有返回值。它表示一个异步执行的计算,当计算完成时,可以执行一些操作,但是不能通过它来获取计算结果。如果需要获取计算结果,则可以使用带返回值的 CompletableFuture.supplyAsync() 方法。
相关问题
CompletableFuture.runAsync 等待
### 使用 `CompletableFuture.runAsync` 并等待其完成
当使用 `CompletableFuture.runAsync` 提交任务时,可以通过调用 `.join()` 或者 `.get()` 来等待任务的完成并处理可能的结果或异常。
#### 方法一:使用 `.join()`
`.join()` 方法会阻塞当前线程直到对应的异步计算完成,并返回结果。对于 `runAsync` 而言,由于其返回的是 `CompletableFuture<Void>`,因此 `.join()` 将不会有任何实际值返回,而是仅用于确认任务已完成[^2]。
```java
public class RunAsyncExample {
public static void main(String[] args) throws InterruptedException {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Running async task...");
try {
Thread.sleep(2000); // Simulate a long-running process.
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Task completed.");
});
System.out.println("Waiting for the task to complete...");
// Wait until completion using join()
future.join();
System.out.println("The asynchronous operation has finished.");
}
}
```
#### 方法二:使用 `.get()`
与 `.join()` 类似,`.get()` 同样会使主线程暂停直至异步任务结束。不同之处在于 `.get()` 可能抛出受检异常(Checked Exception),即如果异步过程中发生了未捕获的异常,则会在调用方处被重新抛出作为 `ExecutionException` 的原因[^4]。
```java
import java.util.concurrent.ExecutionException;
public class RunAsyncGetExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Executing an asynchronous action...");
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Action done!");
});
// Waiting with get(), which can throw exceptions that occurred during execution
future.get();
System.out.println("Asynchronous procedure concluded successfully.");
}
}
```
这两种方式都可以有效地使程序等待由 `runAsync` 发起的操作完成后再继续执行其他逻辑。选择哪种取决于具体的应用场景以及对异常处理的需求。
CompletableFuture.runAsync执行耗时
### 使用 `CompletableFuture.runAsync` 执行长时间运行任务的最佳实践
当使用 `CompletableFuture.runAsync` 来执行可能耗时较长的操作时,有几个最佳实践可以帮助提高程序的效率和可靠性。
#### 设置自定义线程池
默认情况下,`runAsync` 方法会使用公共的 ForkJoinPool.commonPool() 线程池来执行异步操作。然而,在处理大量或长时间运行的任务时,建议创建专用的线程池以避免阻塞其他任务:
```java
ExecutorService customThreadPool = Executors.newFixedThreadPool(10);
CompletableFuture<Void> futureWithCustomPool =
CompletableFuture.runAsync(() -> {
// 长时间运行的任务代码...
}, customThreadPool);
```
通过这种方式可以更好地控制并发度以及资源分配[^1]。
#### 超时机制
为了防止某些异常情况下的无限期等待,可以在调用处设置超时期限。如果超过指定的时间未完成,则抛出 TimeoutException 并取消该 Future 对象:
```java
try {
CompletableFuture<Void> longRunningTask =
CompletableFuture.runAsync(/*...*/);
// 尝试获取结果,最多等待5秒
Void result = longRunningTask.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
// 处理超时错误
}
```
这有助于及时发现潜在问题并采取相应措施[^2]。
#### 错误恢复策略
对于可能出现失败的情况,应该考虑加入重试逻辑或其他形式的容错方案。例如利用 exceptionally 或 handle 方法来进行优雅降级:
```java
CompletableFuture<Void> resilientOperation =
CompletableFuture.runAsync(() -> /* ... */)
.exceptionally(ex -> {
log.error("An error occurred", ex);
return null;
});
```
这样即使遇到不可预见的问题也能保持系统的稳定性和可用性[^3]。
#### 组合多个异步任务
如果有多个相互独立但又需要一起协调工作的子任务,那么可以通过 thenCompose、allOf 和 anyOf 这样的组合器将它们串联起来形成更复杂的流程图结构。比如下面的例子展示了如何同时发起两个请求并将最终的结果汇总在一起:
```java
public PriceResult comparePricesConcurrently(String productId){
CompletableFuture<PriceInfo> priceQuery =
CompletableFuture.supplyAsync(() ->
queryExternalServiceForPrice(productId));
CompletableFuture<PromotionDetails> promoCheck =
CompletableFuture.supplyAsync(() ->
checkPromotionsApplicableToProduct(productId));
return CompletableFuture.allOf(priceQuery,promoCheck).thenApply(v->
combineResultsIntoFinalOutput(
priceQuery.join(),promoCheck.join())
).join();
}
```
这种方法不仅提高了整体吞吐量还简化了业务逻辑之间的依赖关系管理[^4]。
阅读全文
相关推荐
















