![](https://news.xinpengboligang.com/upload/keji/6d2729cb0d84d9da6ff1eda7a025a1fa.jpeg)
thenApply是在同一線程中執行的。
thenApply更具有同步的特性,因為它在執行函數之前會等待當前 future 的完成。
thenApply是在處理函數或 輕量級future 且不涉及長時間運行的計算或阻塞操作時使用。
當需要快速非阻塞,或者當您需要保持嚴格的執行順序時,選擇thenApply 。
thenApplyAsync是另一個線程(通常來自默認線程(ForkJoinPool))異步執行的。
當需要可能長時間運行或想要確保非阻塞行為時,則最好使用thenApplyAsync方法。
當轉換非常耗時或阻塞時,或者想要將處理業務換到另一個線程以保持當前線程響應時,選擇thenApplyAsync。
在下面的示例中,運行 SupplyAsync 的線程將被 processData 方法阻止。除非流程數據返回,否則 SupplyAsync 不會完成。
package org.example;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class ThenApplyExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Simulate a web service call
long startTime = System.nanoTime();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// Fetch data (simulate with sleep)
try {
Thread.sleep(4000); // Simulate delay
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Web Server Data";
});
// Process data asynchronously after fetching
CompletableFuture<String> processedData = future.thenApply(data -> {
// Data processing (CPU-intensive task)
System.out.println("Processing data on thread: " Thread.currentThread().getName());
return processData(data);
});
// Output the processed data
System.out.println("Processed Data: " processedData.get());
long endTime = System.nanoTime();
long duration = (endTime - startTime) / 1_000_000; // Convert to milliseconds
System.out.println("Execution Time: " duration " ms");
}
private static String processData(String data) {
// Simulate data processing
return "Processed " data;
}
}
在下面的示例中,我在線程中運行 SupplyAsync,並且該線程處理階段不會被 processData 方法阻止,因為 processData 方法將在其自己的線程中運行,並且不會阻止 SupplyAsync 。
package org.example;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
public class ThenApplyAsyncExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// Simulate a web service call
long startTime = System.nanoTime();
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// Fetch data (simulate with sleep)
try {
Thread.sleep(4000); // Simulate delay
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Web Server Data";
});
// Process data asynchronously after fetching
CompletableFuture<String> processedData = future.thenApplyAsync(data -> {
// Data processing (CPU-intensive task)
System.out.println("Processing data on thread: " Thread.currentThread().getName());
return processData(data);
});
// Output the processed data
System.out.println("Processed Data: " processedData.get());
long endTime = System.nanoTime();
long duration = (endTime - startTime) / 1_000_000; // Convert to milliseconds
System.out.println("Execution Time: " duration " ms");
}
private static String processData(String data) {
// Simulate data processing
return "Processed " data;
}
}
thenAccept 和 thenAcceptAsync 之間的區別
thenAccept
- thenAccept 是在同一個線程中執行。
- thenAccept適用於對結果執行某些操作,並且該操作是快速非阻塞的情況。當希望維護執行順序或確定代碼將在哪個線程上下文中運行時,thenAccept也非常有用。
thenAcceptAsync
- thenAcceptAsync是為在不同的線程中執行提供的操作,通常取自默認值ForkJoinPool