与CountedCompleter'混淆;java8文档中的示例代码片段
我阅读了java8文档,其中给出了如下示例使用代码:与CountedCompleter'混淆;java8文档中的示例代码片段,java,forkjoinpool,Java,Forkjoinpool,我阅读了java8文档,其中给出了如下示例使用代码: class MyOperation{void apply(E){…} 类ForEach扩展CountedCompleter{ 公共静态void forEach(E[]数组,MyOperation op){ 新的ForEach(null,array,op,0,array.length).invoke(); } 最终E[]数组;最终MyOperation op;最终int lo,hi; ForEach(CountedCompleter p,E[]
class MyOperation{void apply(E){…}
类ForEach扩展CountedCompleter{
公共静态void forEach(E[]数组,MyOperation op){
新的ForEach(null,array,op,0,array.length).invoke();
}
最终E[]数组;最终MyOperation op;最终int lo,hi;
ForEach(CountedCompleter p,E[]数组,MyOperation op,int lo,int hi){
超级(p);
this.array=array;this.op=op;this.lo=lo;this.hi=hi;
}
public void compute(){//version 1
如果(高-低>=2){
int mid=(低+高)>>>1;
setPendingCount(2);//必须在fork之前设置挂起计数
新的ForEach(this,array,op,mid,hi).fork();//右子级
新的ForEach(this,array,op,lo,mid).fork();//左子级
}
否则如果(高>低)
op.apply(数组[lo]);
tryComplete();
}
}
在compute
方法中,每个ForEach对象将分叉两个子任务,并将挂起计数设置为2,
但是在compute
方法的末尾,tryComplete
只能减少一个挂起计数,如何
其余的呢???在阅读了
ForkJoinPool
和CountedCompleter
的源代码后,我终于明白了
从根CountedCompleter派生的所有CountedCompleter将像树一样组织。调用tryComplete
时,如果当前挂起计数为正,它将递减1。否则它将调用当前CountedComplete的onCompletion
,然后递归调用父CountedComplete上的tryComplete
。如果父CountedCompleter为null
,则表示它已经是根CountedCompleter,然后整个任务完成
因此,我们知道:
任务在CountedCompleter
方法完成后不会结束,它将等待直到挂起的计数减为0compute()
任务并不总是由根任务本身结束(与CountedCompleter
和RecursiveTask
非常不同),它可以由child的RecursiveAction
结束tryComplete
class MyOperation{void apply(E){…}
类ForEach扩展CountedCompleter{
公共静态void forEach(E[]数组,MyOperation op){
新的ForEach(null,array,op,0,array.length).invoke();
}
最终E[]数组;最终MyOperation op;最终int lo,hi;
ForEach(CountedCompleter p,E[]数组,MyOperation op,int lo,int hi){
超级(p);
this.array=array;this.op=op;this.lo=lo;this.hi=hi;
}
public void compute(){//version 1
如果(高-低>=2){
int mid=(低+高)>>>1;
setPendingCount(2);//0:+2
新的ForEach(this,array,op,mid,hi).fork();//2:-1
新的ForEach(this,array,op,lo,mid).fork();//3:挂起计数==0完成
}
否则如果(高>低)
op.apply(数组[lo]);
tryComplete();//1:-1
}
}