欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java8 CompletableFuture異步編程解讀

 更新時(shí)間:2024年12月13日 16:02:00   作者:騎個(gè)小蝸牛  
Java8引入的CompletableFuture是Java異步編程的重要進(jìn)展,提供了基于未來(lái)結(jié)果的異步編程模型,它適用于異步計(jì)算、多個(gè)并行任務(wù)組合、異步回調(diào)、超時(shí)控制、錯(cuò)誤處理和多任務(wù)組合與合成等場(chǎng)景

CompletableFuturede介紹

Java 8 引入了 CompletableFuture 類,這是 Java 異步編程的一個(gè)重要進(jìn)展。

CompletableFuture 提供了一種基于未來(lái)結(jié)果的異步編程模型,允許你以更加直觀和易于理解的方式編寫(xiě)非阻塞代碼。

CompletableFuturede使用場(chǎng)景

CompletableFuture 主要用于:

  • 異步計(jì)算:如果你有一些計(jì)算任務(wù)可以異步執(zhí)行,并且不想阻塞主線程,可以使用 CompletableFuture。
  • 多個(gè)并行任務(wù)組合:當(dāng)你有多個(gè)獨(dú)立的異步任務(wù),并且想要在它們都完成后執(zhí)行某些操作時(shí),可以用 CompletableFuture 來(lái)組合它們。
  • 異步回調(diào):當(dāng)異步計(jì)算完成后,你需要執(zhí)行某些后續(xù)操作(如更新 UI、保存結(jié)果等),可以通過(guò) thenApply(), thenAccept(), thenRun() 等方法指定回調(diào)。
  • 超時(shí)控制:可以為異步任務(wù)設(shè)置超時(shí)限制,防止任務(wù)執(zhí)行時(shí)間過(guò)長(zhǎng),導(dǎo)致線程被長(zhǎng)時(shí)間占用。
  • 錯(cuò)誤處理:在異步任務(wù)中,如果有異常發(fā)生,可以通過(guò) handle() 或 exceptionally() 方法進(jìn)行錯(cuò)誤處理。
  • 多任務(wù)的組合與合成:可以將多個(gè)異步任務(wù)的結(jié)果進(jìn)行合成,產(chǎn)生新的任務(wù)。

常用異步編程實(shí)現(xiàn)方案

- Thread

特點(diǎn):

  • Thread是 Java 中最基本的并發(fā)執(zhí)行單位,代表一個(gè)獨(dú)立的執(zhí)行路徑。
  • Thread可以通過(guò)繼承 Thread 類或?qū)崿F(xiàn) Runnable 接口來(lái)創(chuàng)建和啟動(dòng)。
  • 線程會(huì)從 run() 方法開(kāi)始執(zhí)行,run() 方法可以包含任何邏輯。
  • 適合處理簡(jiǎn)單的并發(fā)任務(wù),但不適合復(fù)雜的并發(fā)場(chǎng)景,因?yàn)榫€程管理較為麻煩。

使用示例:

	public static void main(String[] args) {
        Thread thread = new Thread(() -> {
        	 System.out.println(Thread.currentThread().getName() + " is running...");
        });
        thread.start();
    }

- ExecutorService

特點(diǎn):

  • ExecutorService 是一個(gè)用于執(zhí)行異步任務(wù)的接口,通常與線程池一起使用。
  • 它提供了方法來(lái)提交任務(wù)、關(guān)閉線程池、獲取任務(wù)結(jié)果等。
  • ExecutorService 包括多種實(shí)現(xiàn),如 ThreadPoolExecutor,并且支持任務(wù)的異步執(zhí)行。
  • 支持有返回值的任務(wù)(通過(guò) submit() 方法)和無(wú)返回值的任務(wù)(通過(guò) execute() 方法)。

使用示例:

有返回值:

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(2);  // 創(chuàng)建線程池
        
        Callable<Integer> task = () -> {
            Thread.sleep(1000);
            return 42;
        };
        
        Future<Integer> result = executor.submit(task);  // 提交任務(wù)并獲得 Future 對(duì)象
        System.out.println("Task result: " + result.get());  // 獲取結(jié)果
        
        executor.shutdown();  // 關(guān)閉線程池
    }

無(wú)返回值:

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(2);  // 創(chuàng)建線程池
        
        Runnable task = () -> {
            System.out.println(Thread.currentThread().getName() + " is running...");
        };
        
        executor.execute(task);  // 提交任務(wù)
        
        executor.shutdown();  // 關(guān)閉線程池
    }

- CountDownLatch

特點(diǎn):

  • CountDownLatch 是一個(gè)同步輔助類,允許一個(gè)或多個(gè)線程等待直到其他線程完成某個(gè)操作。
  • 使用一個(gè)計(jì)數(shù)器(count)來(lái)表示待完成的任務(wù)數(shù)量,每個(gè)任務(wù)完成后調(diào)用 countDown() 方法,計(jì)數(shù)器減一。
  • 當(dāng)計(jì)數(shù)器為零時(shí),所有等待的線程會(huì)繼續(xù)執(zhí)行。
  • CountDownLatch 不能重用,它適合用于多個(gè)線程并行執(zhí)行后,等待所有線程完成的場(chǎng)景。

使用示例:

    public static void main(String[] args) throws InterruptedException {
        int totalThreads = 3;
        CountDownLatch latch = new CountDownLatch(totalThreads);  // 初始化計(jì)數(shù)器為3
        
        Runnable task = () -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + " finished.");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();  // 每個(gè)線程完成后減少計(jì)數(shù)器
            }
        };
        
        // 啟動(dòng)多個(gè)線程
        for (int i = 0; i < totalThreads; i++) {
            new Thread(task).start();
        }
        
        latch.await();  // 等待計(jì)數(shù)器歸零
        System.out.println("All tasks are finished.");
    }

- CyclicBarrier

特點(diǎn):

  • CyclicBarrier 允許一組線程互相等待,直到所有線程都到達(dá)一個(gè)公共屏障點(diǎn),然后所有線程再一起繼續(xù)執(zhí)行。
  • 它的計(jì)數(shù)器每次歸零后會(huì)重置,適合用來(lái)處理多輪同步任務(wù)。
  • 每當(dāng)所有線程到達(dá)屏障點(diǎn)時(shí),都會(huì)執(zhí)行一個(gè)可選的動(dòng)作(如回調(diào)函數(shù))。

使用示例:

    public static void main(String[] args) throws InterruptedException {
        int totalThreads = 3;
        CyclicBarrier barrier = new CyclicBarrier(totalThreads, () -> {
            System.out.println("All threads reached the barrier point, proceeding...");
        });
        
        Runnable task = () -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + " reached the barrier.");
                barrier.await();  // 等待其他線程到達(dá)屏障點(diǎn)
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
        
        // 啟動(dòng)多個(gè)線程
        for (int i = 0; i < totalThreads; i++) {
            new Thread(task).start();
        }
    }

- ForkJoinPool

特點(diǎn):

  • ForkJoinPool 是專門(mén)用于執(zhí)行遞歸任務(wù)的線程池,特別適合大規(guī)模并行計(jì)算。
  • 它將任務(wù)分割成多個(gè)子任務(wù)并通過(guò)遞歸的方式處理(“fork”),然后合并子任務(wù)的結(jié)果(“join”)。
  • 在 ForkJoinPool 中,任務(wù)拆分采用工作竊取算法,盡量平衡工作負(fù)載,提升性能。

使用示例:

import java.util.concurrent.*;

public class ForkJoinPoolExample {
    public static void main(String[] args) {
        ForkJoinPool pool = new ForkJoinPool();  // 創(chuàng)建 ForkJoinPool
        int[] array = {1, 2, 3, 4, 5, 6, 7, 8};
        RecursiveTask<Integer> task = new SumTask(array, 0, array.length);
        int result = pool.invoke(task);  // 執(zhí)行任務(wù)并獲取結(jié)果
        System.out.println("Sum is: " + result);
    }
}

class SumTask extends RecursiveTask<Integer> {
    private int[] array;
    private int start, end;
    
    public SumTask(int[] array, int start, int end) {
        this.array = array;
        this.start = start;
        this.end = end;
    }
    
    @Override
    protected Integer compute() {
        if (end - start <= 2) {  // 基礎(chǔ)情況
            int sum = 0;
            for (int i = start; i < end; i++) {
                sum += array[i];
            }
            return sum;
        } else {
            int mid = (start + end) / 2;
            SumTask task1 = new SumTask(array, start, mid);
            SumTask task2 = new SumTask(array, mid, end);
            task1.fork();  // 異步執(zhí)行
            task2.fork();
            return task1.join() + task2.join();  // 合并結(jié)果
        }
    }
}

- CompletableFuture

特點(diǎn):

  • CompletableFuture 是 Java 8 引入的異步編程框架,允許你以非阻塞的方式處理任務(wù)。
  • 它支持任務(wù)的組合、回調(diào)、異常處理等,適合用于處理復(fù)雜的異步任務(wù)鏈。
  • 可以通過(guò) supplyAsync()、thenApply() 等方法定義異步任務(wù)的執(zhí)行流程。

使用示例:

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 42;
        });
        
        // 鏈?zhǔn)秸{(diào)用,處理結(jié)果
        CompletableFuture<Integer> result = future.thenApplyAsync(value -> value * 2);
        
        System.out.println("Result: " + result.get());  // 輸出結(jié)果
    }

各種實(shí)現(xiàn)方案總結(jié)

并發(fā)方式特點(diǎn)優(yōu)點(diǎn)缺點(diǎn)
Thread- 最基本的線程創(chuàng)建方式- 通過(guò)繼承Thread 或?qū)崿F(xiàn)Runnable 接口創(chuàng)建任務(wù)- 簡(jiǎn)單直觀- 需要手動(dòng)管理線程,容易資源浪費(fèi)或死鎖- 無(wú)法直接返回任務(wù)結(jié)果- 對(duì)復(fù)雜任務(wù)協(xié)調(diào)不便
ExecutorService- 通過(guò)線程池管理線程- 提供任務(wù)的調(diào)度、執(zhí)行、生命周期管理- 提供線程池避免手動(dòng)創(chuàng)建和銷(xiāo)毀線程,減少資源浪費(fèi)- 支持任務(wù)的結(jié)果返回- 任務(wù)間依賴和組合較復(fù)雜-get() 方法阻塞線程,難以實(shí)現(xiàn)非阻塞
CountDownLatch- 用于等待多個(gè)任務(wù)完成后執(zhí)行后續(xù)操作- 使用計(jì)數(shù)器控制任務(wù)執(zhí)行- 可以控制任務(wù)同步,確保多個(gè)任務(wù)完成后繼續(xù)執(zhí)行- 只適用于等待任務(wù)完成,無(wú)法處理任務(wù)的依賴關(guān)系- 只能使用一次
CyclicBarrier- 用于多個(gè)線程在某一點(diǎn)上等待- 可重復(fù)使用,適合同步多任務(wù)- 可重復(fù)使用,適合多次任務(wù)同步- 不如CompletableFuture 靈活- 僅適合特定的同步場(chǎng)景
ForkJoinPool- 專為遞歸分治任務(wù)設(shè)計(jì)的線程池- 支持任務(wù)拆分和合并- 高效利用多核處理器,適合分治算法- 支持任務(wù)拆分和合并- 對(duì)于非遞歸任務(wù)不適合- 異常處理不如CompletableFuture 靈活
CompletableFuture- 基于Future 設(shè)計(jì)的異步編程API- 支持非阻塞的任務(wù)組合和回調(diào)處理- 支持鏈?zhǔn)秸{(diào)用,異步任務(wù)組合,避免阻塞- 可以處理異常,支持并行處理和同步等待- 支持thenApply、thenAccept 等多種處理方式,簡(jiǎn)化代碼- 復(fù)雜任務(wù)時(shí)調(diào)試?yán)щy- 異常處理仍較為復(fù)雜- 比ExecutorService 稍顯復(fù)雜
  • Thread:最基礎(chǔ)的并發(fā)方式,直接通過(guò)線程控制執(zhí)行,但缺乏高級(jí)功能。
  • ExecutorService:基于線程池的高層接口,能夠有效管理線程資源和任務(wù)執(zhí)行。
  • CountDownLatch、CyclicBarrier:用于線程間的同步協(xié)調(diào)。CountDownLatch 等待特定任務(wù)完成,而 CyclicBarrier 可重復(fù)用于多次任務(wù)同步。
  • ForkJoinPool:適用于任務(wù)拆分和合并的場(chǎng)景,特別是遞歸分治任務(wù)。
  • CompletableFuture:提供更靈活的異步任務(wù)處理方式,支持鏈?zhǔn)秸{(diào)用、異步執(zhí)行及異常處理,適合復(fù)雜的并發(fā)任務(wù)調(diào)度。

CompletableFuturede結(jié)構(gòu)

CompletableFuture實(shí)現(xiàn)了Future接口和CompletionStage接口。

結(jié)構(gòu)梳理

相關(guān)接口描述
Future是一個(gè)表示異步計(jì)算結(jié)果的接口。它提供了方法來(lái)檢查異步計(jì)算是否完成、獲取計(jì)算的結(jié)果以及取消計(jì)算。
CompletionStage是一個(gè)表示異步計(jì)算結(jié)果的接口,提供了處理計(jì)算結(jié)果的非阻塞操作。與 Future 不同,CompletionStage 采用鏈?zhǔn)秸{(diào)用,可以更靈活地組合多個(gè)異步操作。

- Future接口

Future接口是JDK 5引入的,該接口屬于java.util.concurrent包。

Future接口的目的是表示異步計(jì)算的結(jié)果,它允許你提交一個(gè)任務(wù)給一個(gè) Executor(執(zhí)行器),并在稍后獲取任務(wù)的結(jié)果。

主要方法:

方法描述
get()阻塞當(dāng)前線程,直到異步計(jì)算完成,并返回計(jì)算結(jié)果
get(long timeout, TimeUnit unit)阻塞當(dāng)前線程,直到異步計(jì)算完成或超時(shí),并返回計(jì)算結(jié)果
isDone()檢查異步計(jì)算是否完成
cancel(boolean mayInterruptIfRunning)嘗試取消異步計(jì)算
isCancelled()檢查異步計(jì)算是否被取消。

- CompletionStage接口

CompletionStage 接口是 Java 8 引入的一個(gè)重要接口,用于描述異步計(jì)算的生命周期和結(jié)果。

CompletionStage 提供了一套方法,用于處理異步計(jì)算的結(jié)果、組合多個(gè)計(jì)算、處理異常等。

主要方法:

方法描述
thenApply在當(dāng)前階段完成后,應(yīng)用給定的 Function,并返回一個(gè)新的 CompletionStage。
thenAcceptAsync異步地執(zhí)行指定的 Consumer,并返回一個(gè)新的 CompletionStage,該階段沒(méi)有結(jié)果。
thenComposeAsync異步地將當(dāng)前階段的結(jié)果應(yīng)用于一個(gè)返回 CompletionStage 的函數(shù),并返回一個(gè)新的 CompletionStage。
thenCombine在兩個(gè) CompletionStage 都完成后,使用給定的 BiFunction 合并它們的結(jié)果,并返回一個(gè)新的 CompletionStage。
runAfterEitherAsync在任意一個(gè)給定的兩個(gè) CompletionStage 完成后,異步地執(zhí)行指定的 Runnable。
thenAccept在當(dāng)前階段完成后,執(zhí)行指定的 Consumer,并返回一個(gè)新的 CompletionStage,該階段沒(méi)有結(jié)果。
runAfterEither在任意一個(gè)給定的兩個(gè) CompletionStage 完成后,執(zhí)行指定的 Runnable。
thenCombineAsync在兩個(gè) CompletionStage 都完成后,異步地使用給定的 BiFunction 合并它們的結(jié)果,并返回一個(gè)新的 CompletionStage。
thenAcceptBothAsync在兩個(gè) CompletionStage 都完成后,異步地執(zhí)行指定的 BiConsumer,并返回一個(gè)新的 CompletionStage。
applyToEither在兩個(gè) CompletionStage 中任意一個(gè)完成后,應(yīng)用給定的 Function,并返回一個(gè)新的 CompletionStage。
applyToEitherAsync在兩個(gè) CompletionStage 中任意一個(gè)完成后,異步地應(yīng)用給定的 Function,并返回一個(gè)新的 CompletionStage。
runAfterBothAsync在兩個(gè) CompletionStage 都完成后,異步地執(zhí)行指定的 Runnable,并返回一個(gè)新的 CompletionStage。
thenAcceptBothAsync在兩個(gè) CompletionStage 都完成后,異步地執(zhí)行指定的 BiConsumer。
acceptEitherAsync在兩個(gè) CompletionStage 中任意一個(gè)完成后,異步地執(zhí)行指定的 Consumer,并返回一個(gè)新的 CompletionStage。
handleAsync異步地處理當(dāng)前階段的結(jié)果或異常,應(yīng)用給定的 BiFunction,并返回一個(gè)新的 CompletionStage。
thenComposeAsync同 thenCompose,但異步地應(yīng)用給定的函數(shù),并返回一個(gè)新的 CompletionStage。
thenCombineAsync同 thenCombine,但異步地使用給定的 BiFunction 合并兩個(gè) CompletionStage 的結(jié)果。
exceptionally如果當(dāng)前階段以異常完成,則應(yīng)用指定的 Function 處理該異常,并返回一個(gè)新的 CompletionStage。
acceptEither在兩個(gè) CompletionStage 中任意一個(gè)完成后,執(zhí)行指定的 Consumer。
thenCompose將當(dāng)前階段的結(jié)果應(yīng)用于一個(gè)返回 CompletionStage 的函數(shù),并返回一個(gè)新的 CompletionStage。
handle處理當(dāng)前階段的結(jié)果或異常,應(yīng)用給定的 BiFunction,并返回一個(gè)新的 CompletionStage。
thenAcceptBoth在兩個(gè) CompletionStage 都完成后,執(zhí)行指定的 BiConsumer。
thenApplyAsync異步地應(yīng)用給定的 Function,并返回一個(gè)新的 CompletionStage。
whenCompleteAsync異步地執(zhí)行指定的 BiConsumer,無(wú)論結(jié)果如何,并返回一個(gè)新的 CompletionStage。
applyToEitherAsync同 applyToEither,但異步地應(yīng)用給定的 Function,并返回一個(gè)新的 CompletionStage。
acceptEitherAsync同 acceptEither,但異步地執(zhí)行指定的 Consumer,并返回一個(gè)新的 CompletionStage。
runAfterEitherAsync同 runAfterEither,但異步地執(zhí)行指定的 Runnable,并返回一個(gè)新的 CompletionStage。
thenRunAsync異步地執(zhí)行指定的 Runnable,并返回一個(gè)新的 CompletionStage,該階段沒(méi)有結(jié)果。
runAfterBoth在兩個(gè) CompletionStage 都完成后,執(zhí)行指定的 Runnable。
whenComplete在當(dāng)前階段完成后,無(wú)論結(jié)果如何,執(zhí)行指定的 BiConsumer,并返回一個(gè)新的 CompletionStage。
thenRunAsync異步地執(zhí)行指定的 Runnable,并返回一個(gè)新的 CompletionStage,該階段沒(méi)有結(jié)果。

常用方法

方法描述
supplyAsync()異步地運(yùn)行一個(gè)帶返回值的任務(wù)。
runAsync()異步地運(yùn)行一個(gè)無(wú)返回值的任務(wù)。
thenApply()當(dāng) CompletableFuture 任務(wù)完成時(shí)執(zhí)行某個(gè)操作,并返回新的結(jié)果。
thenAccept()當(dāng)任務(wù)完成時(shí)執(zhí)行某個(gè)操作,但不返回結(jié)果。
thenRun()當(dāng)任務(wù)完成時(shí)執(zhí)行某個(gè)操作,無(wú)需返回結(jié)果。
exceptionally()用于處理任務(wù)執(zhí)行中發(fā)生的異常。
handle()處理任務(wù)執(zhí)行中的正常結(jié)果或異常結(jié)果。
allOf()等待多個(gè) CompletableFuture 全部完成,返回一個(gè)新的 CompletableFuture。
anyOf()等待多個(gè) CompletableFuture 中的任意一個(gè)完成。

CompletableFuture使用示例

1. 基本異步操作

CompletableFuture.supplyAsync() 和 CompletableFuture.runAsync() 是最常用的啟動(dòng)異步任務(wù)的方法。

  • supplyAsync() 用于執(zhí)行帶返回值的異步任務(wù)。
  • runAsync() 用于執(zhí)行不帶返回值的異步任務(wù)。
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 帶返回值的異步任務(wù)
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);  // 模擬耗時(shí)任務(wù)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 42;  // 返回結(jié)果
        });

        // 獲取異步任務(wù)的結(jié)果
        Integer result = future.get();  // 阻塞,直到任務(wù)完成
        System.out.println("Result: " + result);
    }

2. 任務(wù)鏈?zhǔn)秸{(diào)用

通過(guò) thenApply(), thenAccept(), thenRun() 等方法,可以將多個(gè)異步任務(wù)串聯(lián)在一起。

  • thenApply() 用于處理任務(wù)的返回值。
  • thenAccept() 用于消費(fèi)返回值,但不返回結(jié)果。
  • thenRun() 用于執(zhí)行沒(méi)有返回值的操作。
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            return 42;  // 返回結(jié)果
        });

        // 鏈?zhǔn)秸{(diào)用,先處理結(jié)果,再轉(zhuǎn)換
        CompletableFuture<Integer> resultFuture = future
            .thenApply(value -> value * 2)  // 將值乘以2
            .thenApply(value -> value + 10);  // 再加10

        Integer result = resultFuture.get();  // 獲取最終結(jié)果
        System.out.println("Final Result: " + result);  // 輸出 94
    }

3. 多個(gè)異步任務(wù)組合

使用 thenCombine()、thenCompose()、allOf() 和 anyOf() 等方法可以組合多個(gè)異步任務(wù),執(zhí)行復(fù)雜的操作。

  • thenCombine() 用于將兩個(gè)獨(dú)立的異步任務(wù)的結(jié)果合并。
  • thenCompose() 用于將第一個(gè)異步任務(wù)的結(jié)果作為參數(shù)傳遞給下一個(gè)異步任務(wù)。
  • allOf() 用于等待多個(gè)異步任務(wù)完成,并且不關(guān)心每個(gè)任務(wù)的結(jié)果。
  • anyOf() 用于等待多個(gè)異步任務(wù)中的任意一個(gè)完成。

示例1:組合兩個(gè)異步任務(wù)

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            return 10;
        });

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            return 20;
        });

        // 合并兩個(gè)任務(wù)的結(jié)果
        CompletableFuture<Integer> combinedFuture = future1
            .thenCombine(future2, (result1, result2) -> result1 + result2);  // 將兩個(gè)結(jié)果相加

        Integer result = combinedFuture.get();  // 獲取最終結(jié)果
        System.out.println("Combined Result: " + result);  // 輸出 30
    }

示例2:使用 allOf() 等待多個(gè)任務(wù)完成

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("Task 1 completed");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(1500);
                System.out.println("Task 2 completed");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 等待多個(gè)任務(wù)全部完成
        CompletableFuture.allOf(future1, future2).join();

        System.out.println("All tasks are completed.");
    }

4. 異常處理

在異步任務(wù)中,異??赡軙?huì)發(fā)生。CompletableFuture 提供了 exceptionally() 和 handle() 方法來(lái)處理異常。

  • exceptionally() 用于捕獲異常并提供替代值。
  • handle() 可以處理正常結(jié)果和異常。
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
            if (true) {
                throw new RuntimeException("Something went wrong!");
            }
            return 42;
        });

        // 使用 exceptionally 處理異常并提供默認(rèn)值
        CompletableFuture<Integer> resultFuture = future.exceptionally(ex -> {
            System.out.println("Exception occurred: " + ex.getMessage());
            return -1;  // 返回默認(rèn)值
        });

        Integer result = resultFuture.get();  // 獲取結(jié)果
        System.out.println("Result: " + result);  // 輸出 -1
    }

5. 并行執(zhí)行多個(gè)任務(wù)

使用 CompletableFuture.supplyAsync() 或 runAsync() 來(lái)并行執(zhí)行多個(gè)任務(wù),然后使用 allOf() 或 anyOf() 等方法等待這些任務(wù)的完成。

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
                return 1;
            } catch (InterruptedException e) {
                return 0;
            }
        });

        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(500);
                return 2;
            } catch (InterruptedException e) {
                return 0;
            }
        });

        // 等待所有任務(wù)完成并合并結(jié)果
        CompletableFuture<Integer> result = future1
            .thenCombine(future2, (res1, res2) -> res1 + res2);  // 將兩個(gè)結(jié)果相加

        System.out.println("Combined result: " + result.get());  // 輸出 3
    }

6. 處理返回值的轉(zhuǎn)換

通過(guò) thenApply() 等方法可以對(duì)異步任務(wù)的結(jié)果進(jìn)行轉(zhuǎn)換處理。

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 10);

        // 轉(zhuǎn)換結(jié)果:將值乘以2
        CompletableFuture<Integer> transformedFuture = future.thenApply(value -> value * 2);

        System.out.println("Transformed Result: " + transformedFuture.get());  // 輸出 20
    }

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring為java.util.Properties類型的屬性進(jìn)行賦值過(guò)程解析

    spring為java.util.Properties類型的屬性進(jìn)行賦值過(guò)程解析

    這篇文章主要介紹了spring為java.util.Properties類型的屬性進(jìn)行賦值過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 利用Lambda表達(dá)式創(chuàng)建新線程案例

    利用Lambda表達(dá)式創(chuàng)建新線程案例

    這篇文章主要介紹了利用Lambda表達(dá)式創(chuàng)建新線程案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • Java單例的寫(xiě)法詳解

    Java單例的寫(xiě)法詳解

    在java中,單例有很多種寫(xiě)法,面試時(shí),手寫(xiě)代碼環(huán)節(jié),除了寫(xiě)算法題,有時(shí)候也會(huì)讓手寫(xiě)單例模式,這里記錄一下單例的幾種寫(xiě)法和優(yōu)缺點(diǎn)。需要的朋友可以參考下
    2021-09-09
  • 在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    在Map中實(shí)現(xiàn)key唯一不重復(fù)操作

    這篇文章主要介紹了在Map中實(shí)現(xiàn)key唯一不重復(fù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java調(diào)用WebService服務(wù)的三種方式總結(jié)

    Java調(diào)用WebService服務(wù)的三種方式總結(jié)

    雖然WebService這個(gè)框架已經(jīng)過(guò)時(shí),但是有些公司還在使用,在調(diào)用他們的服務(wù)的時(shí)候就不得不面對(duì)各種問(wèn)題,本篇文章總結(jié)了最近我調(diào)用?WebService的心路歷程,3種方式可以分別嘗試,需要的朋友可以參考下
    2023-08-08
  • JAVA后臺(tái)實(shí)現(xiàn)文件批量下載方式

    JAVA后臺(tái)實(shí)現(xiàn)文件批量下載方式

    這篇文章主要介紹了JAVA后臺(tái)實(shí)現(xiàn)文件批量下載方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java實(shí)現(xiàn)ssh登錄linux并執(zhí)行命令的三種實(shí)現(xiàn)方式

    java實(shí)現(xiàn)ssh登錄linux并執(zhí)行命令的三種實(shí)現(xiàn)方式

    文章介紹了三種在Java中實(shí)現(xiàn)SSH登錄Linux并執(zhí)行命令的方法,包括使用ganymed-ssh2、jsch和sshd-core,由于ganymed-ssh2和jsch的最新版本較舊,可能無(wú)法與較新的Linux系統(tǒng)兼容,而sshd-core一直在更新,推薦使用
    2024-11-11
  • Java中替換HTML標(biāo)簽的方法代碼

    Java中替換HTML標(biāo)簽的方法代碼

    這篇文章主要介紹了Java中替換HTML標(biāo)簽的方法代碼,需要的朋友可以參考下
    2014-02-02
  • 新浪開(kāi)源輕量級(jí)分布式RPC框架motan簡(jiǎn)單示例解析

    新浪開(kāi)源輕量級(jí)分布式RPC框架motan簡(jiǎn)單示例解析

    這篇文章主要為大家介紹了新浪開(kāi)源輕量級(jí)分布式RPC框架motan的簡(jiǎn)單示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • Java中TimedCache緩存對(duì)象的詳細(xì)使用教程

    Java中TimedCache緩存對(duì)象的詳細(xì)使用教程

    TimedCache是一個(gè)泛型類,它的主要作用通常是在一定時(shí)間范圍內(nèi)對(duì)特定鍵值對(duì)進(jìn)行緩存,并且能夠根據(jù)設(shè)定的時(shí)間策略來(lái)自動(dòng)清理過(guò)期的緩存項(xiàng),本文給大家介紹了Java中TimedCache緩存對(duì)象的詳細(xì)使用教程,需要的朋友可以參考下
    2024-12-12

最新評(píng)論