Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
与CountedCompleter'混淆;java8文档中的示例代码片段_Java_Forkjoinpool - Fatal编程技术网

与CountedCompleter'混淆;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[]

我阅读了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[]数组,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
    任务在
    compute()
    方法完成后不会结束,它将等待直到挂起的计数减为0
  • CountedCompleter
    任务并不总是由根任务本身结束(与
    RecursiveTask
    RecursiveAction
    非常不同),它可以由child的
    tryComplete
    结束
然后让我们看一下Java8doc中的代码片段(注意序列号0:1:2:3:在代码中,这是一种可能的执行顺序):

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
}
}