CountedCompleter的示例

 class MyMapper<E> { E apply(E v) {  ...  } }
 class MyReducer<E> { E apply(E x, E y) {  ...  } }
 class MapReducer<E> extends CountedCompleter<E> {
   final E[] array; final MyMapper<E> mapper;
   final MyReducer<E> reducer; final int lo, hi;
   MapReducer<E> sibling;
   E result;
   MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper,
              MyReducer<E> reducer, int lo, int hi) {
     super(p);
     this.array = array; this.mapper = mapper;
     this.reducer = reducer; this.lo = lo; this.hi = hi;
   }
   public void compute() {
     if (hi - lo >= 2) {
       int mid = (lo + hi) >>> 1;
       MapReducer<E> left = new MapReducer(this, array, mapper, reducer, lo, mid);
       MapReducer<E> right = new MapReducer(this, array, mapper, reducer, mid, hi);
       left.sibling = right;
       right.sibling = left;
       setPendingCount(1); // only right is pending
       right.fork();
       left.compute();     // directly execute left
     }
     else {
       if (hi > lo)
           result = mapper.apply(array[lo]);
       tryComplete();
     }
   }
   public void onCompletion(CountedCompleter<?> caller) {
     if (caller != this) {
       MapReducer<E> child = (MapReducer<E>)caller;
       MapReducer<E> sib = child.sibling;
       if (sib == null || sib.result == null)
         result = child.result;
       else
         result = reducer.apply(child.result, sib.result);
     }
   }
   public E getRawResult() { return result; }

   public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
     return new MapReducer<E>(null, array, mapper, reducer,
                              0, array.length).invoke();
   }
 }

 以上是一个CountedCompleter (Java Platform SE 8 )给的一个示例。

1、在进行任务分割的函数compute()中觉得需要注意的点是else逻辑中if(hi > lo)条件满足执行mapper运算。这里的条件个人觉得没有必要吧。因为跳出上面的if(hi - lo >=2)这个判断条件时不应该是(hi - lo >=1)么。既然(hi - lo 已经大于等于1了,hi > lo 还有必要判断吗?)不知道大家怎么看。

2、第2个问题是需要理解onCompletion(CountedCompleter<?> caller)中的if(this != caller)这个判断条件的含义。可以看到在tryComplete()调用中执行CountedCompleter子类覆盖的onCompletion()方法。会发现有s==a==this这种场景,在onCompletion()执行中通过this->a,caller ->s,且this==caller时不能进行reduce归并即oneTask.onCompletion(oneTask)场景过滤掉,只有在parentTask.onCompletion(subTask)这种场景才进行归并。所以我们看到

//当前this任务是caller的父任务。
//归并caller和它的sibling,归并后的结果保证至父任务this的result
MapReducer<E> child = (MapReducer<E>)caller;
MapReducer<E> sib = child.sibling;
if (sib == null || sib.result == null)
    result = child.result;
else
    result = reducer.apply(child.result, sib.result);

/* 尝试设置完成当前任务 */public final void tryComplete() {

    CountedCompleter<?> a = this, s = a;
    for (int c;;) {
        /* pending 为 0 代表当前没有未完成的任务 */
        if ((c = a.pending) == 0) {
            /* 默认空实现 */
            a.onCompletion(s);
            /* 递归父任务,找到顶任务 */
            if ((a = (s = a).completer) == null) {
                s.quietlyComplete(); // 设置 status 为 NORMAL
                return;
            }
        }
        /* CAS 设置 pending - 1 */
        else if (U.compareAndSwapInt(a, PENDING, c, c - 1))
            return;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值