public final Void getRawResult() { return null; }
public final void setRawResult(Void v) {}
}
对于stack处理
- postFire方法: 通知其依赖的节点,进行完成传播;由于没有使用锁,只使用了原子操作,这样可以防止,有些节点加入到依赖集合中,却不能得到执行
- cleanStack方法:清除失活以及无效的节点
- postComplete方法:执行stack集合中任务
- casStack方法:改变队尾操作
- tryPushStack方法:尝试加入队尾数据
- pushStack:队尾加入数据
3.2 Completion以及子类
Completion类,抽象类,待执行的任务节点;其内部持有下个流以及流任务执行的逻辑;其继承关系类图如下:
内部变量
CompletableFuture dep;
CompletableFuture src;
CompletableFuture snd
dep代表当前操作新成的流节点,src、snd为其依赖的流节点;其中每个类,还有流任务执行的对象:Runable、Function、ConSumer、BiFunction、BiConsumer等
tryFire方法很重要,其持有的转换对象、消费对象代表了需要执行的操作;其实他们对应的tryFire方法内部实际操作,都在CompletableFuture内有对应方法
tryFire方法
很关键的方法,其持有的转换对象、消费对象代表了需要执行的操作;其情况与具体的模式有关,其情况如下
- SYNC = 0, 同步状态;执行线程为当前方法调用线程或者上个流执行所在线程;同时其可能仅仅是为了启动线程池启动任务
- ASYNC = 1,异步,表示需要在线程池内执行
- NESTED = -1,传播模式,表示依赖的流节点已经处于完成状态,正在传递处理
claim方法
线程池任务提交,并且执行有且提交一次
3.3 中间流生成与执行原理
中间流处理,就是CompletionStage声明的方法;其系列处理方法,基本逻辑相同,也就是方法名称不同而已,而由于持有的任务不同而略有不同
3.3.1 thenRun系列
均是通过私有方法uniRunStage进行处理,进行添加时尝试处理的
private CompletableFuture uniRunStage(Executor e, Runnable f) {
if (f == null) throw new NullPointerException();
CompletableFuture d = newIncompleteFuture();
if (e != null || !d.uniRun(this, f, null)) {
UniRun c = new UniRun(e, d, this, f);
push©;
c.tryFire(SYNC);
}
return d;
}
对于此方法有下面逻辑
- 同步执行,且uniRun执行成功,则返回生成流节点
- 否则,添加相应Completion子类到等待集合中,并再次尝试执行;和之前提到的postFire结合确保一定能够执行
final boolean uniRun(CompletableFuture<?> a, Runnable f, UniRun<?> c) {
Object r; Throwable x;
if (a == null || (r = a.result) == null || f == null)
return false;
if (result == null) {
if (r instanceof AltResult && (x = ((AltResult)r).ex) != null)
completeThrowable(x, r);
else
try {
if (c != null && !c.claim())
return false;
f.run();
completeNull();
} catch (Throwable ex) {
completeThrowable(ex);
}
}
return true;
}
方法的最后一个参数,当是触发线程池提交任务操作时,需要传入任务实例,否则传入空指;也就是传入空指,代表此方法中直接执行,这时,线程可能为生成流节点方法线程,也可能是上个流节点执行的线程,也可能是线程池创建的线程中(好像等于白说了);这个方法流程如下:
-
检验依赖节点执行状态,未完成则结束
-
执行异常结束,则设置异常状态,结束
-
正常执行结束时,尝试执行当前任务
- 需要向线程池提交任务,则通过claim方法,进行处理,并返回;提交任务后会执行tryFire方法
- 不需要向线程池提交任务,执行;若执行成功,有结果直接设置结果,无结果设置NIL值;若是发生已成设置异常
如果调用CompletionStage声明的方法未能立刻执行的,则需要通过依赖的流节点完成后通过postComplete方法进行分发;
final void postComplete() {
CompletableFuture<?> f = this; Completion h; while ((h = f.stack) != null || (f != this && (h = (f = this).stack) != null)) { CompletableFuture<?> d; Completion t;
if (f.casStack(h, t = h.next)) {
if (t != null) {
if (f != this) {
pushStack(h);
continue;
}
h.next = null;
}
f = (d = h.tryFire(NESTED)) == null ? this : d;
}
}
}
tryFire方法,返回空表示流节点任务没有完成,否则表示已完成,继续这个节点的分发;也就是分发时通过tryFire方法去执行依赖节点的任务
final CompletableFuture tryFire(int mode) {
CompletableFuture d; CompletableFuture a;
if ((d = dep) == null ||
!d.uniRun(a = src, fn, mode > 0 ? null : this))
return null;
dep = null; src = null; fn = null;
return d.postFire(a, mode);
}
逻辑如下
- 当前任务执行的流节点为空、或者未执行,则返回null,也就是此节点未完成操作
- 已经执行成功,则把持有对象全部置空,以便gc;并通过postFire通知其依赖节点进行清理依赖节点集合或者继续传播触发
final CompletableFuture postFire(CompletableFuture<?> a, int mode) {
if (a != null && a.stack != null) {
if (mode < 0 || a.result == null)
a.cleanStack();
else
a.postComplete();
}
if (result != null && stack != null) {
if (mode < 0)
return this;
else
postComplete();
}
return null;
}
主要逻辑
- 依赖流节点不为空,且依赖集合不为空
- 传播模式或者其未完成执行,则进行节点清理
- 否则,进行传播
- 当前流节点执行完毕,且依赖集合不为空
- 正在处于传播模式,则返回当前对象,继续传播
- 否则,进行传播处理
整个添加流节点以及执行流程,已经分析完了;那么这个相似处,根据这个例子再来具体的说下:
整个流程:Completion子类(UniRun)以及子类tryFire方法、CompletableFuture中辅助方法(uniRun)以及postFire、postComplete等分发方法
3.3.2 thenRun相似流程系列
- thenApply系列方法:子类UniApply、辅助方法uniApply
- thenAccept系列方法:子类UniAccept、辅助方法uniAccept
- thenCombine系列方法:子类BiApply、辅助方法biApply
- thenAcceptBoth系列方法:子类BiAccept、辅助方法biAccept
- runAfterBoth系列方法:子类biRun、辅助方法BiRun
- applyToEither系列方法:子类orApply、辅助方法OrApply
- acceptEither系列方法:子类OrAccept、辅助方法orAccept
- runAfterEither系列方法:子类OrRun、辅助方法orRun
- handle系列方法:子类UniHandle、辅助方法uniHandle
- whenComplete系列方法:子类UniWhenComplete、辅助方法uniWhenComplete
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
以前一直是自己在网上东平西凑的找,找到的东西也是零零散散,很多时候都是看着看着就没了,时间浪费了,问题却还没得到解决,很让人抓狂。
后面我就自己整理了一套资料,还别说,真香!
资料有条理,有系统,还很全面,我不方便直接放出来,大家可以先看看有没有用得到的地方吧。
617662)]
[外链图片转存中…(img-kFqVMy8s-1711744617662)]
[外链图片转存中…(img-lmvkJWJ5-1711744617662)]
[外链图片转存中…(img-ZntzpGBF-1711744617663)]
[外链图片转存中…(img-KudJ1S8Z-1711744617663)]
[外链图片转存中…(img-W4RYrswo-1711744617663)]