当前位置: 首页 >Java技术 > 高级-08异步&线程池(CompletableFuture)

高级-08异步&线程池(CompletableFuture)

一、线程基础

1、初始化线程的4种方式

  • 继承 Thread
  • 实现 Runnable 接口
  • 实现 Callable 接口 + FutureTask
  • 线程池

1.1 继承Thread

class Thread_1 extends Thread{@Overridepublic void run() {System.out.println("当前线程" + Thread.currentThread().getName());}}new Thread_1().start();

1.2 实现 Runnable 接口

class Run implements Runnable{@Overridepublic void run() {System.out.println("当前线程" + Thread.currentThread().getName());}}new Thread(new Run()).start();

1.3 实现 Callable 接口 + FutureTask

可以拿到返回结果,可以处理异常

class Call implements Callable<Integer> {@Overridepublic Integer call() throws Exception {System.out.println("当前线程" + Thread.currentThread().getName());retu 2;}}FutureTask<Integer> futureTask = new FutureTask<>(new Call());new Thread(futureTask).start();Integer integer = futureTask.get();// 阻塞,抛出异常

主进程可以获取线程的运算结果,但是不利于控制服务器中的线程资源。可能导致服务器资源耗尽。

1.4 线程池

业务代码中,之前三种启动线程方式都不会用。

而是【将所有的多线程异步任务交给线程池去执行】

通过线程池控制资源,性能稳定,也可以获取执行结果,并捕获异常。

但是,在业务复杂情况下,一个异步调用可能会依赖于另一个异步调用的结果。

// 最好保证当前系统中只有一两个线程池public static ExecutorService service = Executors.newFixedThreadPool(10);// submit可以获取返回值Future<Integer> submit = service.submit(new Call());Integer in = submit.get();// execute没有返回值service.execute(new Run());

还可以自定义线程池

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

2、开发中为什么使用线程池

  • 降低资源的消耗
    • 通过重复利用已经创建好的线程降低线程的创建和销毁带来的損耗。
  • 提高响应速度
    • 因为线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行。
  • 提高线程的可管理性
    • 线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配。

二、CompletableFuture 异步编排

1、创建异步对象

public static ExecutorService executor = Executors.newFixedThreadPool(10);// 1、runAsync没有返回值CompletableFuture.runAsync(() -> {	System.out.println("Runnable 的 run 方法");}, executor);// 2、supplyAsync可以获取返回值CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {	retu "返回值";}, executor);completableFuture.get(); // 接收返回值,阻塞

2、计算完成时回调方法

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {	retu "返回值"; // 可以返回值}, executor).whenComplete((res, exception) -> {// 感知异常,但无法修改数据System.out.println("异步任务成功完成了");System.out.println("异步任务结果:" + res + ";异常为:" + exception);}).exceptionally(throwable -> {// 感知异常,并且返回默认值retu "默认返回值";});completableFuture.get();

方法不以 Async 结尾,意味着 Action 使用相同的线程执行,而 Async 可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

3、handle

任务执行完的处理方法

CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {retu "返回值"; // 可以返回值}, executor).handle((res,exception)->{if(res == null){retu "";}retu res + "01";});completableFuture.get();

4、线程串行化方法

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

5、两任务组合-都要完成

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

// 定义两个异步对象CompletableFuture<String> future01 = CompletableFuture.supplyAsync(() -> {retu "返回值1";}, executor);CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {retu "返回值2";}, executor);// 两任务组合future01.runAfterBothAsync(future02,()->{System.out.println("run 线程03");},executor);future01.thenAcceptBothAsync(future02,(res1,res2)->{System.out.println("之前结果" + res1 + "》》" + res2);},executor);future01.thenCombineAsync(future02,(res1,res2)->{retu res1 + res2;},executor);

6、两任务组合-一个完成

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

7、多任务组合

高级-08异步&线程池(CompletableFuture) _ JavaClub全栈架构师技术笔记

allOf 等待所有任务完成

anyOf 只要有一个任务完成

CompletableFuture<Void> all = CompletableFuture.allOf(future01, future02, future03);all.get(); // 阻塞,不加这个的话主线程会继续走// 分别获取各个线程的返回值String s = future01.get();CompletableFuture<Object> any = CompletableFuture.anyOf(future01, future02, future03);Object o = any.get(); // 获取最先完成线程的返回值

作者:这杯Java有毒
来源链接:https://www.cnblogs.com/yanyaqiblog/p/13965873.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。





本文链接:https://www.javaclub.cn/java/117161.html

分享给朋友:

“高级-08异步&线程池(CompletableFuture)” 的相关文章

Dubbo原理浅析 2022年05月15日 21:53:58
windows下kafka搭建 2022年05月15日 21:58:15
Centos 6.4最小化安装后的优化(1) 2022年05月16日 19:50:13
网络协议 2022年05月16日 20:32:41
网络协议栈基本知识 2022年05月16日 20:33:52
Java实现阶乘运算 2022年05月21日 11:37:18
我对java String的理解 及 源码浅析 2022年05月27日 23:07:01