concurrent之线程池executorService和forkJoin用法

executorService:线程池

根据cpu核数设置线程池线程个数,编写任务类

代码如下:

package com.demo;

import java.util.ArrayList;
import java.util.concurrent.*;
import java.util.stream.LongStream;

/**
 * @Description
 * @Author by mocar小师兄
 * @Date 2020/3/10 14:56
 **/
public class ExecutorServiceTest {
    private ExecutorService executorService;
    private int availableProcessors;

    public ExecutorServiceTest() {
        availableProcessors = Runtime.getRuntime().availableProcessors();
        executorService = Executors.newFixedThreadPool(availableProcessors);
    }

    private static class Sumtask implements Callable{
        private long[] arr;
        private int from;
        private int to;

        public Sumtask(long[] arr, int from, int to) {
            this.arr = arr;
            this.from = from;
            this.to = to;
        }

        @Override
        public Long call() throws Exception {
            Long total = 0l;
            for (int i = from; i <= to; i++) {
                total += arr[i];
            }
            System.out.println("当前线程: "+Thread.currentThread().getName() + "计算的值为:" + total);
            return total;
        }
    }


    public long sumUp(long[] number){
        ArrayList> futures = new ArrayList<>();
        int part = number.length / availableProcessors;
        for (int i = 0; i < availableProcessors; i++) {
            int from=0;
            int to =0;
            from = i * part;
            to = (i == availableProcessors-1 ? number.length-1 : (i+1) * part - 1);
            Future retData = executorService.submit(new ExecutorServiceTest.Sumtask(number, from, to));
            futures.add(retData);
        }
        long total= 0;
        try {
            for (Future longFuture : futures) {
                total += longFuture.get();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        /*try {
            total = futures.stream().map(Future::get).reduce(0, (a, b) -> a + b);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        return total;

    }

    public static void main(String[] args) {
        long[] number = LongStream.rangeClosed(1, 100).toArray();
        ExecutorServiceTest executorServiceTest = new ExecutorServiceTest();
        long ret = executorServiceTest.sumUp(number);
        System.out.println(ret);
    }
}

concurrent之线程池executorService和forkJoin用法_第1张图片

 

 

forkJoin:拆解成几个小任务,递归

根据cpu核数设置

package com.demo;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.stream.LongStream;

/**
 * @Description
 * @Author by mocar小师兄
 * @Date 2020/3/10 11:39
 **/
public class ForkJoinTest{
    public static int count =1;

    //执行任务RecursiveTask:有返回值  RecursiveAction:无返回值
    private static class sumTask extends RecursiveTask {
        private long[] arr;
        private int from;
        private int to;

        public sumTask(long[] arr, int from, int to) {
            this.arr = arr;
            this.from = from;
            this.to = to;
        }

        @Override
        protected Long compute() {

            int avaCpu = Runtime.getRuntime().availableProcessors();
            boolean canCompute = count >= avaCpu;
            Long total = 0l;
            if (canCompute){
                for (int i = from; i <=to ; i++) {
                    total += arr[i];
                }

            }else {//拆分
                System.out.println("=========任务拆分=========");
                int middle = (from + to) / 2;
                sumTask left = new sumTask(arr, from, middle);
                sumTask right = new sumTask(arr, middle + 1, to);
                left.fork();
                right.fork();
                count ++;
                total= left.join() + right.join();
            }
            return total;
        }
    }

    public static void main(String[] args) {
        long[] number = LongStream.rangeClosed(1, 100).toArray();
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        sumTask sumTask = new sumTask(number, 0, 99);
        ForkJoinTask submit = forkJoinPool.submit(sumTask);
        try {
            Long aLong = submit.get();
            System.out.println(aLong);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}

 

 

concurrent之线程池executorService和forkJoin用法_第2张图片

 

参考:

https://blog.csdn.net/m0_37542889/article/details/92640903

你可能感兴趣的:(concurrent)