1. 程式人生 > 其它 >Intel Triple-speed Ethernet IP 使用筆記(二)

Intel Triple-speed Ethernet IP 使用筆記(二)

什麼是ForkJoin 並行執行任務 提高效率(大資料量時)

大資料:MapReduce 把大任務拆分為小任務

ForkJoin

ForkJoin特點 工作竊取 維護了一個雙端佇列

當兩個執行緒同時執行時,其中一個執行緒先執行完,可以偷取未執行完執行緒的工作幫助它執行

ForkJoin操作

定義一個計算類繼承 RecursiveTask

/*求和計算*/
public class ForkJoinTest extends RecursiveTask<Long> {
    private Long start;
    private Long end;
    private Long temp=100000L;

    public ForkJoinTest(Long start, Long end) {
        this.start = start;
        this.end = end;
    }

    //如果小於臨界值,就用普通方式,否則使用forkJoin方式
    @Override
    protected Long compute() {
        if(end-start<temp){
            //分支合併計算 如何使用forkJoin
            /*
             * 1. forkJoinPool
             * 2. 計算任務,forkJoinPool.execute(ForkJoinTask task)
             * 3. 計算類繼承 RecursiveTask<Long> 類*/
            Long sum=0L;
            for(Long i=start;i<=end;i++)
            {
                sum=sum+i;
            }
            return sum;

        }else{
            long middle=(start+end)/2;
            ForkJoinTest task1 = new ForkJoinTest(start, middle);
            task1.fork();  //拆分任務,把任務壓入執行緒佇列
            ForkJoinTest task2 = new ForkJoinTest(middle + 1, end);
            task2.fork();

            return task1.join()+task2.join();  //返回結果
        }
    }
}

測試類

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        test3();
    }
    //普通方式
    //sum=500000000500000000 時間:3594
    public static void test1(){
        long sum=0L;
        long start=System.currentTimeMillis();
        for(Long i=1L;i<=10_0000_0000;i++){
            sum=sum+i;
        }
        long end=System.currentTimeMillis();

        System.out.println("sum="+sum+" 時間:"+(end-start));
    }
    //ForkJoin
    //sum=500000000500000000 時間:4256  可以調節
    public static void test2() throws ExecutionException, InterruptedException {

        long start=System.currentTimeMillis();

        ForkJoinPool forkJoinPool = new ForkJoinPool();
        ForkJoinTest task = new ForkJoinTest(0L, 10_0000_0000L);
        //forkJoinPool.execute(task);  //執行任務 同步
        ForkJoinTask<Long> submit = forkJoinPool.submit(task);//提交任務 非同步
        Long sum = submit.get();

        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+" 時間:"+(end-start));
    }
    //Stream並行流
    //sum=500000000500000000 時間:234  最優方案
    public static void test3(){
        long start=System.currentTimeMillis();


        long sum = LongStream.rangeClosed(0L, 10_0000_0000L).parallel().reduce(0L, Long::sum);

        long end=System.currentTimeMillis();
        System.out.println("sum="+sum+" 時間:"+(end-start));
    }
}

ForkJoin必須是在大資料量時使用