1.Vert.x 源码解析(4.x)——Future源码解析
2.研发必会-异步编程利器之CompletableFuture(含源码 中)
3.HTTP连接池及源码分析(二)
4.c++基础语法之future,源码promise,解析async详细讲解-SurfaceFlinger学习必备c++知识
Vert.x 源码解析(4.x)——Future源码解析
在现代软件开发中,源码异步编程的解析重要性日益凸显,提升并发性能并处理大量并行操作。源码Vert.x,解析阿里云头像源码作为一款基于事件驱动和非阻塞设计的源码异步框架,提供了丰富的解析工具简化异步编程。本文将深入解析Vert.x 4.x版本的源码Future源码,理解其关键类和功能。解析1. 异步核心
Vert.x的源码核心在于FutureImpl和PromiseImpl,它们是解析实现异步操作的关键。AsyncResult是源码通用接口,用于表示异步操作的解析结果,包含成功值或失败异常。源码2. Future类详解
Future扩展了AsyncResult,提供了组合操作如join、any、all和map等功能。内部的FutureInternal主要负责添加监听器,FutureBase负责执行监听器和转换函数。 具体来说,FutureImpl的onComplete方法接收一个handler,任务完成后执行,而tryComplete则在异步操作有结果时触发,最终调用用户指定的handler。 相比之下,Promise允许用户手动设置异步结果,PromiseImpl继承自FutureImpl,并增加了context获取功能。乐趣棋牌源码组件3. 实例与源码分析
通过简单的入门实例,如独立使用Future,我们可以看到Vert.x如何通过创建PromiseImpl获取Future。源码分析显示,Promise.future获取Future,OnComplete用于添加监听,而complete方法则用于设置值并通知监听器。4. 深入源码
在源码层面,addListener和emitSuccess方法在OnComplete中扮演重要角色。而complete方法,特别是tryComplete,是设置值并触发监听的关键。5. 总结
总的来说,理解Vert.x中的Future,就是创建PromiseImpl获取Future,通过OnComplete添加监听器,然后通过Promise的complete方法设置值并通知监听器。后续还将深入探讨其他Future实现类,如all、any和map的原理。研发必会-异步编程利器之CompletableFuture(含源码 中)
微信公众号访问地址: 研发必会-异步编程利器之CompletableFuture(含源码 中)
近期热推文章:
1、springBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表;
2、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据;
3、基于Redis的Geo实现附近商铺搜索(含源码)
4、基于Redis实现关注、取关、大兴离朝阳源码共同关注及消息推送(含源码)
5、SpringBoot整合多数据源,并支持动态新增与切换(详细教程)
6、基于Redis实现点赞及排行榜功能
7、研发必会-异步编程利器之CompletableFuture(上)
一、多任务组合回调
备注:源码获取方式在文底。
1.1、AND组合关系
thenCombine / thenAcceptBoth / runAfterBoth都表示:将两个CompletableFuture组合起来,只有这两个都正常执行完了,才会执行某个任务。也即:当任务一和任务二都完成再执行任务三(异步任务)。
区别在于:
1、runAfterBoth:不会把执行结果当做方法入参,且没有返回值。
2、thenAcceptBoth:会将两个任务的执行结果作为方法入参,传递到指定方法中,且无返回值。
3、thenCombine:会将两个任务的执行结果作为方法入参,传递到指定方法中,且有返回值。
代码案例:
运行结果:
1.2、OR组合关系
将两个CompletableFuture组合起来,只要其中一个执行完了,就会执行某个任务。(两个任务,只要有一个任务完成,就执行任务三)
区别在于:
1、哪有聊天软件源码runAfterEither:不会把执行结果当做方法入参,且没有返回值。
2、acceptEither: 会将已经执行完成的任务,作为方法入参,传递到指定方法中,且无返回值。
3、applyToEither:会将已经执行完成的任务,作为方法入参,传递到指定方法中,且有返回值。(个人推荐)
参考代码:
返回结果:
若将异步任务中的Thread.sleep()改为,将输出的结果为:
从结果中不难对比发现,任务的参数是任务和任务中执行最快的返回结果。
注意:若把核心线程数量改为1,会是什么样的呢?
运行结果:
从上面看出,改为1就变成单线程执行了。
1.3、多任务组合(allOf\anyOf)
1.allOf:等待所有任务都执行完成后,才会执行 allOf 返回的CompletableFuture。如果任意一个任务异常,allOf的CompletableFuture,执行get方法,会抛出异常。(等待所有任务完成才会执行)
2.anyOf:任意一个任务执行完,就执行anyOf返回的CompletableFuture。如果执行的任务异常,anyOf的语言连麦源码CompletableFuture,执行get方法,会抛出异常。(只要有一个任务完成)
参考案例:
结果返回:
从结果中看出:等待所有任务都执行完成后,才会执行 allOf 返回的CompletableFuture。
同理anyOf,只需要调整代码:
运行结果:
1.4、thenCompose
thenCompose方法会在某个任务执行完成后,将该任务的执行结果,作为方法入参,去执行指定的方法。该方法会返回一个新的CompletableFuture实例。
1、如果该CompletableFuture实例的result不为null,则返回一个基于该result新的CompletableFuture实例;
2、如果该CompletableFuture实例为null,然后就执行这个新任务。
代码案例:
结果:
二、使用注意点
CompletableFuture 使异步编程更加便利的、代码更加优雅的同时,也要关注使用的一些注意点。
2.1、Future需要获取返回值,才能获取异常信息
代码案例:
输出结果:
Future需要获取返回值(res.get()),才能获取到异常信息。如果不加 get()/join()方法,看不到异常信息。使用的时候,注意一下,考虑是否加try…catch…或者使用exceptionally方法。
若改成exceptionally方法,无需get或join也可以捕获异常信息:
结果:
2.2、CompletableFuture的get()方法是阻塞的
CompletableFuture的get()方法是阻塞的,如果使用它来获取异步调用的返回值,需要添加超时时间。
推荐使用:
2.3、建议使用自定义线程池,不要使用默认的
CompletableFuture代码中使用了默认的线程池,处理的线程个数是电脑CPU核数-1。在大量请求过来的时候,处理逻辑复杂的话,响应会很慢。一般建议使用自定义线程池,优化线程池配置参数。
参考案例:
但是如果线程池拒绝策略是DiscardPolicy或者DiscardOldestPolicy,当线程池饱和时,会直接丢弃任务,不会抛弃异常。因此建议,CompletableFuture线程池策略最好使用AbortPolicy,然后耗时的异步线程,做好线程池隔离。
说明:
AbortPolicy(默认):直接抛弃
CallerRunsPolicy:用调用者的线程执行任务
DiscardOldestPolicy:抛弃队列中最久的任务
DiscardPolicy:抛弃当前任务。
三、源码获取方式
更多优秀文章,请关注个人微信公众号或搜索“程序猿小杨”查阅。然后回复:源码,可以获取对应的源码,开箱即可使用。
如果大家对相关文章感兴趣,可以关注微信公众号"程序猿小杨",会持续更新优秀文章!欢迎大家 分享、收藏、点赞、在看,您的支持就是我坚持下去的最大动力!谢谢!
参考网站:
blog.csdn.net/ThinkWon/...
mp.weixin.qq.com/s/shjA...
HTTP连接池及源码分析(二)
HTTP连接池的实现原理及源码解读
本文深入探讨了HTTP连接池的设计思路,从执行原理到源码分析,解答了一系列关键问题。首先,连接池通过构建HttpClient,利用建造者模式灵活配置属性,隐藏构建细节,确保客户端代码简洁易读。HttpClient的执行链遵循责任链模式,请求在一系列Executor(执行器)中按顺序传递,每个执行器负责处理请求的一部分。
连接池的核心是PoolEntry,它是连接的基本单位,包含HttpRoute信息和连接状态。连接池通过LinkedList管理空闲和等待队列,确保性能优化,如优先使用新用过的连接而非等待队列的过期连接。连接的获取和释放采用异步操作,使用Future对象确保线程阻塞和唤醒的精确控制。
在连接池的管理中,如何分配和回收连接、设置连接保持时间、检测连接可用性,以及处理可能遇到的问题,如底层连接关闭而上层未识别等,都有详细的过程和策略。连接池的参数设置,如超时时间、最大连接数,需要根据具体业务需求和系统限制进行调整。
源码中,原子类在Future对象的使用引发了疑问,实际上,即使每个线程拥有独立的Future,原子类确保了关键状态在并发环境中的原子性。至于等待线程的唤醒顺序,使用signalAll可能不是最优解,因为这可能唤醒所有等待线程,而非最久等待的那个。
总的来说,HTTP连接池的设计既考虑了性能优化,又注重并发控制,源码中的这些细节体现了其复杂性和灵活性。理解这些原理和实践案例,可以帮助开发者更好地运用HTTP连接池并解决实际问题。
c++基础语法之future,promise,async详细讲解-SurfaceFlinger学习必备c++知识
在SurfaceFlinger源码分析中,我遇到了一些新的C++基础语法,比如future和promise。这些工具的引入,使得在多线程环境中访问异步操作的结果变得更加方便。
传统上,在C++中,我们需要通过创建线程并使用`join`等待线程完成,然后将结果赋值给变量。这种过程相对繁琐。为了解决这个问题,C++引入了`std::future`来访问异步操作的结果。`future`类不能立即获取结果,而是在异步操作完成后,通过同步等待或者查询状态来获取结果。`future`的状态有三种:未开始(`future_status::deferred`)、已完成(`future_status::ready`)、超时(`future_status::timeout`)。
`std::async`函数用于创建异步任务,结果保存在`future`对象中。当需要获取异步结果时,通过`future.get()`方法来完成。如果只关注任务完成,可以使用`future.wait()`方法。`async`函数的参数包括线程创建策略(如`std::launch::async`、`std::launch::deferred`)、要执行的函数和函数执行时需要传递的参数。
`std::promise`类帮助线程赋值。在线程函数中,通过`promise`对象的`set_value`方法为外部传递的`promise`赋值。在任务完成后,可以通过`promise`对象关联的`future`获取设置的值。
在实际应用中,`promise`和`future`的结合使得在多线程环境下访问异步操作的结果更加灵活。例如,在SurfaceFlinger源码中,`future`用于等待子线程执行完成,并通过`set_value`设置结果,`get`方法用于获取结果。这种结合使得源码分析更加简便。
为了深入理解这些新语法,我查阅了相关文档,并实践了在SurfaceFlinger源码中的应用。同时,我还使用了性能分析工具如`perfetto`和`systrace`来验证代码的运行效果。这些实践不仅帮助我学习了C++的新语法,还加深了对SurfaceFlinger源码的理解。
如果你对这些C++基础语法感兴趣,或者想要了解SurfaceFlinger源码的详细分析,可以参考我的视频教程,或者私聊我进行深入探讨。我的文章和视频内容涵盖了C++基础语法的学习,以及如何将其应用于实际的SurfaceFlinger源码分析。