乐趣区

关于java:JAVA并发编程CompletableFuture的方法介绍和使用

1.CompletableFuture 的办法简介和应用

2. 总结

1.CompletableFuture 的办法简介和应用
从下面那篇博客 JAVA 并发编程——Future 和 CompletableFuture 的简介与应用 咱们对 CompletableFuture 有了一个大略的理解和初步的应用,接下来咱们来零碎介绍一下 CompletableFuture 这个类有哪些办法。

1.0 根底的运行办法

// 无返回值, 相似 Runnable 可抉择传入一个线程池
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
 // 有返回值,相似 Future 可抉择传入一个线程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)

1.1 取得后果和触发计算的办法

public T    get();// 始终阻塞获取后果,和 Future 的 get()办法雷同
public T    get(long timeout, TimeUnit unit);// 在肯定工夫内获取后果,没取得后果就抛异样
public T    getNow(T valueIfAbsent);// 马上获取后果,如果没获取到后果就返回传入参数的默认值。
public T    join(); // 和 get()办法雷同,区别是 join()不会抛出异样,get()会抛出异样
public boolean complete(T value) // 在计算未实现的状况下,立即打断 get 办法立刻返回括号值

1.2 对计算结果进行解决的办法

thenApply() 
// 计算结果存在依赖关系,先执行上一步再执行下一步
// 因为存在依赖关系(以后步错,不走下一步),以后步骤有异样的话就叫停。
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
{
// 当一个线程依赖另一个线程时用 thenApply 办法来把这两个线程串行化,
CompletableFuture.supplyAsync(() -> {
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
        System.out.println("111");
return 1024;
    }).thenApply(f -> {System.out.println("222");
return f + 1;
    }).thenApply(f -> {
//int age = 10/0; // 异常情况:那步出错就停在那步。System.out.println("333");
return f + 1;
    }).whenCompleteAsync((v,e) -> {// 当实现的时候
        System.out.println("*****v:"+v);
    }).exceptionally(e -> {// 当产生异样的时候
        e.printStackTrace();
return null;
    });

    System.out.println("----- 主线程完结,END");

// 主线程不要立即完结,否则 CompletableFuture 默认应用的线程池会立即敞开:
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
}

}

// 有异样也能够往下一步走,依据带的异样参数能够进一步解决
handle()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
    {
// 当一个线程依赖另一个线程时用 handle 办法来把这两个线程串行化,
        // 异常情况:有异样也能够往下一步走,依据带的异样参数能够进一步解决
CompletableFuture.supplyAsync(() -> {
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
            System.out.println("111");
return 1024;
        }).handle((f,e) -> {
int age = 10/0;
            System.out.println("222");
return f + 1;
        }).handle((f,e) -> {System.out.println("333");
return f + 1;
        }).whenCompleteAsync((v,e) -> {System.out.println("*****v:"+v);
        }).exceptionally(e -> {e.printStackTrace();
return null;
        });

        System.out.println("----- 主线程完结,END");

// 主线程不要立即完结,否则 CompletableFuture 默认应用的线程池会立即敞开:
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
    }


}

1.3 对计算结果进行生产的办法

// 接管工作的处理结果,并生产解决,无返回后果
thenAccept();
// 工作 A 执行完执行 B,并且 B 不须要 A 的后果
thenRun();
// 工作 A 执行完执行 B,B 须要 A 的后果,然而工作 B 无返回值
thenAccept();
// 工作 A 执行完执行 B,B 须要 A 的后果,同时工作 B 有返回值
thenApply();
public static void main(String[] args) throws ExecutionException, InterruptedException
{CompletableFuture.supplyAsync(() -> {return 1;}).thenApply(f -> {return f + 2;}).thenApply(f -> {return f + 3;}).thenApply(f -> {return f + 4;}).thenAccept(r -> System.out.println(r));
}

1.4 对计算速度进行选用的办法

// 谁快用谁
applyToEither()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
    {CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
// 暂停几秒钟线程
try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); }
return 10;
        });

        CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); }
return 20;
        });

        CompletableFuture thenCombineResult = completableFuture1.applyToEither(completableFuture2,f -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return f + 1;
        });

        System.out.println(Thread.currentThread().getName() + "\t" + thenCombineResult.get());
    }
}

1.5 对计算结果进行合并的办法

// 两个 CompletionStage 工作都实现后,最终能把两个工作的后果一起交给 thenCombine 来解决
thenCombine()
public class CompletableFutureDemo2
{public static void main(String[] args) throws ExecutionException, InterruptedException
    {CompletableFuture completableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return 10;
        });

        CompletableFuture completableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return 20;
        });

        CompletableFuture thenCombineResult = completableFuture1.thenCombine(completableFuture2, (x, y) -> {System.out.println(Thread.currentThread().getName() + "\t" + "---come in");
return x + y;
        });

        System.out.println(thenCombineResult.get());
    }
}

2. 总结

这篇博客咱们总结了 CompletableFuture 的根底办法,咱们还是须要在生产上多加练习,遗记 api 的时候能够看一下源码或者从新翻阅一下这篇博客。

退出移动版