-
tryComplete:当前点为出发点,向依赖其节点进行循环处理,遇到以下情况会结束
- pending为0且依赖其的节点为空:pending为0时,回调onCompletion完成处理方法;若依赖其节点为空,则调用quietlyComplete方法设置执行状态为完成
- 处理当前节点pending值-1成功
-
propagateCompletion方法,和tryComplete方法相比,无onCompletion方法回调调用,也即对于每个中间任务无需关注
-
quietlyCompleteRoot : 依照指针域去寻找根依赖节点,并为其设置正常结束状态;比较暴力的结束任务状态,这种适合于找到某一个结果就停止
onCompletion回调方法
这个方法是仅仅通知当前任务所有依赖已经完成,用于任务合并操作,但却在此方法中仅仅知道最后一个完成的依赖任务;
为何CountedCompleter要设置正常结束状态,这时由于ForkJoinTask在执行方法的逻辑
final int doExec() {
int s; boolean completed;
if ((s = status) >= 0) {
try {
completed = exec();
} catch (Throwable rex) {
return setExceptionalCompletion(rex);
}
if (completed)
s = setCompletion(NORMAL);
}
return s;
}
也即是,现有ForkJoinTask的子类exec方法,均是返回true,而只有CountedCompleter返回false,所以其需要设置正常结束状态,任务才会被结算成执行完毕,在任务fork等调用时,才会结束阻塞;如果你只是往里面添加一个任务这个则不处理也没有关系
类似RecursiveAction的效果
class Task(private val num : Int,private val end : Int, completer: Task? = null) : CountedCompleter<Void>(completer) {
override fun compute() {
if (end == num) {
if (end % 2 == 0) println("odd $end")
propagateCompletion()
return
}
addToPendingCount(1)
val middle = (num + end) / 2
Task(num, middle, this).fork()
Task(middle + 1, end,this).fork()
}
}
类似RecursiveTask的效果
class Task(val num : Int,val end : Int, completer: Task? = null) : CountedCompleter<Int>(completer) {
@Volatile public var mResult = 0
private var t1 : Task? = null
private var t2 : Task? = null
override fun compute() {
if (end == num) {
mResult = end
tryComplete()
return
}
addToPendingCount(1)
val middle = (num + end) / 2
t1 = Task(num, middle, this).fork() as Task
t2 = Task(middle + 1, end,this).fork() as Task
}
override fun onCompletion(caller: CountedCompleter<*>?) {
if (this != caller && caller is Task) {
mResult = (t1?.mResult ?: 0) + (t2?.mResult ?: 0)
}
}
override fun getRawResult(): Int {
return mResul