Fork/Join练习

Fork/Join框架用于实现高效的并行计算,包括ForkJoinPool线程池和ForkJoinTask。该框架通过RecursiveAction和RecursiveTask进行任务分解与合并。工作原理涉及多工作队列和工作窃取策略,例如在计算斐波那契数列和统计词频等场景中应用。
  • Fork是对任务的分解,Join对应结果合并
  • Fork/Join计算框架主要包含两部分,一部分是分治任务的线程池ForkJoinPool,另一部分是ForkJoinTask。类似ThreadPoolExecutor和Runnable的关系。
  • ForkJoinTask有两个子类-- RecursiveAction和RecursiveTask,都定义了抽象方法compute() ,RecursiveTask的compute()有返回值。
  • ForkJoinPool工作原理:
  • 内部有多个 工作队列, 当调用 ForkJoinPool的 submit()或invoke()提交任务,ForkJoinPool会根据一定的路由规则把任务提交到一个任务队列中,如果任务在执行过程中会创建出子任务,那么子任务会提交到工作线程对应的任务队列中。
  • 支持工作窃取
  1. 斐波那契数列
package forkjoin;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

class Fibtask extends RecursiveTask<Integer>{
    final int n;
    Fibtask(int n)
    {
        this.n = n;
    }

    @Override
    protected Integer compute() {
        if (n<=1)return n;
        Fibtask f1 = new Fibtask(n-1);
        f1.fork();
        Fibtask f2 = new Fibtask(n-2);
        return f2.compute()+ f1.join();
    }
}

public class FibV2 {

    public static void main(String[] args) {

        Long start = System.currentTimeMillis();
        ForkJoinPool forkJoinPool = new ForkJoinPool(1);
        Integer res = forkJoinPool.invoke(new Fibtask(33));
        System.out.println(res);
        Long end = System.currentTimeMillis();
        System.out.println(end-start);
    }

}

  1. 统计词频
package forkjoin;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

class MR extends RecursiveTask<Map<String,Long>>{
    private String[]fc;
    private int start,end;

    public MR(String[]fc, int start,int end)
    {
        this.fc = fc;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Map<String, Long> compute() {
        if (start==end)
        {
            return calc(fc[start]);
        }else {
            int mid = (start + end)/2;
            MR f1 = new MR(fc,start,mid);
            f1.fork();
            MR f2 = new MR(fc,mid+1,end);
            return merge(f1.join(),f2.compute());
        }
    }



    private Map<String,Long>merge(Map<String,Long>r1,Map<String,Long>r2)
    {
        Map<String,Long>res = new HashMap<>();
        res.putAll(r1);
        r2.forEach((k,v)->{res.put(k,res.getOrDefault(k,0L)+v);});
        return res;
    }

    private Map<String,Long>calc(String line)
    {
        Map<String,Long>result = new HashMap<>();
        String[]words = line.split("\\s+");
        for (String w:words)
        {
            result.put(w,result.getOrDefault(w,0L)+1);
        }
        return result;
    }
}

public class countFreq {

    public static void main(String[] args) {
        Long start = System.currentTimeMillis();
        String[]fc = {"hello world","hello me","hello fork","hello join","fork join in world"};
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        Map<String,Long>res = forkJoinPool.invoke(new MR(fc,0,fc.length-1));
        res.forEach((k,v)->{
            System.out.println(String.format("%s freq: %d",k,v));
        });
        Long end = System.currentTimeMillis();
        System.out.println(end-start);

    }

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值