ForkJoinPool多任務拆分子任務

jdk1.7後提供多線程多任務拆分子任務

List<GpsCoordHistroy> datalistCar ;
 
//方式2:多任務方式
SumTask task = new SumTask(datalistCar, kafkaTemplate, 0, datalistCar.size());
//創建一個通用池,這個是jdk1.8提供的功能
ForkJoinPool pool = ForkJoinPool.commonPool();
//提交分解的SumTask 任務
Future<Integer> future = pool.submit(task);
try {
    long e = System.currentTimeMillis();
    logger.warn("當前線程處理數量:" +future.get()+"原始數據量:"+ datalistCar.size() + "共耗時" + (e - s) + "毫秒");
} catch (Exception e) {
    e.printStackTrace();
} finally {
    //關閉線程池
    pool.shutdown();

}

 

/**
 * 多線程同步處理大任務拆分子任務方式
 */
public class SumTask extends RecursiveTask<Integer> {
    /**
     * 每個小任務 最多隻累加1000個
     */
    private static final int THRESHOLD = 1000;
    private Logger logger = LoggerFactory.getLogger(getClass());
    private KafkaTemplate kafkaTemplate;
    private List<GpsCoordHistroy> datalist;
    /**
     * 任務集合開始點
     */
    private int start;
    /**
     * 任務集合結束點
     */
    private int end;

    public SumTask(List<GpsCoordHistroy> datalist, KafkaTemplate kafkaTemplate, int start, int end) {
        this.datalist = datalist;
        this.kafkaTemplate = kafkaTemplate;
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        if (end-start <= THRESHOLD) {
            sendKafKa(datalist.subList(start,end));
            return end-start;
        } else {
            int middle = (start+ end)/2;
            SumTask left = new SumTask(datalist,kafkaTemplate, start, middle);
            SumTask right = new SumTask(datalist,kafkaTemplate, middle, end);
            //並行執行兩個 小任務
            left.fork();
            right.fork();
            //把兩個小任務累加的結果合併起來
            return left.join()+right.join();
        }
    }
private void sendKafKa(List<GpsCoordHistroy> currentList) {}

雖說了ForkJoinPool會把大任務拆分成多個子任務,但是ForkJoinPool並不會爲每個子任務創建單獨的線程。相反,池中每個線程都有自己的雙端隊列(Deque)用於存儲任務。這個雙端隊列對於工作竊取算法至關重要。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章