ForkJoinPool線程池

1.  拆分線程池的使用場景是什麼?java

答: 是對一組連續的數據進行耗時操做,例如 一個 大小爲 1000萬 的集合 進行操做。json

       例子: 對1000萬個數據進行排序,那麼會將這個任務分割成兩個500萬的排序任務和一個針對這兩組500萬數據的合併任務。以此類推,對於500萬的數據也會作出一樣的分割處理,到最後會設置一個閾值來規定當數據規模到多少時,中止這樣的分割處理。好比,當元素的數量小於10時,會中止分割,轉而使用插入排序對它們進行排序。數組

 

2.   如何使用 ForkJoinPool?
 答: (1)客戶端中使用:構建一個任務,將任務推到 線程池中 ide

          (2)構建任務:this

                      2.1 三變量google

                          數組數據spa

                          begin;   //數組數據中開始下標線程

                          end   //數組數據中結束3d

                  2.2   compare中 執行,拆分任務(關鍵是拆分數據),合併code

    例子(該代碼未運行): 

public class RecursiveActionTest extends RecursiveTask<Integer> {
    private static final long serialVersionUID = -3611254198265061729L;
    //閥值(是數組的大小/線程數算出來的)
    public  final int threshold = 0;
    //這兒應該有一個數組
    private int[] bigNum={1,2,3,.....1000000000000};
    private int start;
    private int end;
    private int threadNum=1;

    public RecursiveActionTest(int start, int end) {
        this.start = start;
        this.end = end;
    }
    
   //設置線程數並設置閥值
    public void init(int threadNum){
        this.threadNum=threadNum;
        threshold = end/threadNum;
    }

    //compute 是一個遞歸任務
    @Override
    protected Integer compute() {
        int sum = 0;

        //若是任務足夠小就計算任務
        boolean canCompute = (end - start) <= threshold;
        if (canCompute) {    //執行加法任務(任務爲 對 數組 start位的數據到end位,求和)
            for (int i = start; i <= end; i++) {
                // 每一個任務爲:sum+i
                sum += bigNum[i];
            }
        } else {
            // 若是任務大於閾值,就分裂成10子任務計算,step:每一份的任務數
            int step = (start + end) /threadNum ;
            ArrayList<RecursiveActionTest> subTaskList = new ArrayList<RecursiveActionTest>();
            int pos = start;
            //設置每一個小任務的始起始值和終止值

            for (int i = 0; i < threadNum; i++) {
                int lastOne = pos + step;
                if (lastOne > end) lastOne = end;
                //pos和 lostOne其實對應數組中下標
                RecursiveActionTest subTask = new RecursiveActionTest(pos, lastOne);
                pos += step + 1;
                subTaskList.add(subTask);
                //把子任務推向線程池
                subTask.fork();
            }
            // 等待全部子任務完成,並計算值
            for (RecursiveActionTest task : subTaskList) {
                sum += task.join();
            }
        }

      return sum;
    }

    public static void main(String[] args) {
        ForkJoinPool forkjoinPool = new ForkJoinPool();

        //生成一個計算任務,計算1+2+3+4
        RecursiveActionTest task = new RecursiveActionTest(1, 1000000000000);

        //執行一個任務
        Future<Integer> result = forkjoinPool.submit(task);

        try {
            System.out.println(result.get());
        } catch (Exception e) {
            System.out.println(e);
        }
    }

}

            

                      

 

 

3. 用 forkJoinPool 將 100 萬個 User對象 放進一個 JsonArray,用個人電腦雙核 用時 5.6 S,用單線程,一個For循環,用時 6.6 S

@Test
    public void test2(){
       JsonArray jsonArray= new JsonArray();
        long start = System.currentTimeMillis();
        System.out.println(start);
        for (int i = 0; i <1000000 ; i++) {
            User user = new User();
            user.setId(i);
            user.setAge("232"+i);
            user.setName("張三");
            JsonObject jObj=new JsonObject();
            jObj.addProperty("id", i);
            jObj.addProperty("age", 20);
            jObj.addProperty("name", "張三");

            jsonArray.add(jObj);
        }
        long middel = System.currentTimeMillis();

        //將 JsonArray中數據轉換成集合
        List<User> users = JsonUtils.jsonToList(jsonArray.toString(), User.class);
        long end = System.currentTimeMillis();
        System.out.println("將對象一個一個轉換成JsonArray:"+(middel-start));


        System.out.println("JsonArray轉換成List"+(end-middel));
 }

 

 

package com.xuecheng.manage_cms;

import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

import java.util.ArrayList;
import java.util.concurrent.ForkJoinPool;

import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

public class ForkJoinListTest extends RecursiveTask<JsonArray> {
    private static final long serialVersionUID = -3611254198265061729L;
    //閥值
    public static  int threshold=0 ;
    private int start;
    private int end;
    //線程數
    private int threadNum = 4;
    public ForkJoinListTest(int start, int end) {
        this.start = start;
        this.end = end;


    }

    /**
     * 初始化閥值   只在主線程中調用
     */
    public void init(){

        threshold = end/threadNum;
    }


    @Override
    protected JsonArray compute() {
        JsonArray bigJsonArray= new JsonArray();

        //若是任務足夠小就計算任務
        boolean canCompute = (end - start) <= threshold;
        if (canCompute) {    //執行加法任務
           // JsonArray jsonArray= new JsonArray();
            for (int i = start; i <= end; i++) {
                User user = new User();
                user.setId(i);
                user.setAge("232"+i);
                user.setName("張三");
                JsonObject jObj=new JsonObject();
                jObj.addProperty("id", i);
                jObj.addProperty("age", 20);
                jObj.addProperty("name", "張三");

                bigJsonArray.add(jObj);
            }
        } else {
            // 若是任務大於閾值,就分裂成10子任務計算,step:每一份的任務數
            int step = (start + end) / threadNum;
            ArrayList<ForkJoinListTest> subTaskList = new ArrayList<ForkJoinListTest>();
            int pos = start;
            //設置每一個小任務的始起始值和終止值

            for (int i = 0; i < threadNum; i++) {
                int lastOne = pos + step;
                if (lastOne > end) lastOne = end;

                ForkJoinListTest subTask = new ForkJoinListTest(pos, lastOne);
                pos += step + 1;
                subTaskList.add(subTask);
                //把子任務推向線程池
                subTask.fork();
            }
            // 等待全部子任務完成,並計算值

            for (ForkJoinListTest task : subTaskList) {

                bigJsonArray.addAll(task.join());
            }
        }

        return bigJsonArray;
    }


    public static void main(String[] args) {
        ForkJoinPool forkjoinPool = new ForkJoinPool();

        //生成一個計算任務,計算1+2+3+4
        ForkJoinListTest task = new ForkJoinListTest(1, 1000000);
        //須要初始化閥值
        task.init();
        long begain = System.currentTimeMillis();
        //執行一個任務
        Future<JsonArray> result = forkjoinPool.submit(task);

        try {
            JsonArray jsonElements = result.get();
            long end = System.currentTimeMillis();
           // System.out.println(jsonElements);
            System.out.println("耗時:"+(end-begain));
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

 

相關文章
相關標籤/搜索