<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 100  文章 - 50  trackbacks - 0
    <2016年12月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    收藏夾

    我收藏的一些文章!

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    一、任務分解問題和ForkJoinPool簡介

           在多線程并發編程中,有時候會遇到將大任務分解成小任務再并發執行的場景。Java 8新增的ForkJoinPool很好的支持了這個問題。

           ForkJoinPool是一種支持任務分解的線程池,當提交給他的任務“過大”,他就會按照預先定義的規則將大任務分解成小任務,多線程并發執行。

          一般要配合可分解任務接口ForkJoinTask來使用,ForkJoinTask有兩個實現它的抽象類:RecursiveAction和RecursiveTask,其區別是前者沒有返回值,后者有返回值。

              下面通過具體代碼,來示范兩個問題:(1)怎么定義可分解的任務類 (2)如何使用ForkJoinPool

    package demo.thread.fork;


    import java.util.Random;

    import java.util.concurrent.ExecutionException;

    import java.util.concurrent.ForkJoinPool;

    import java.util.concurrent.Future;

    import java.util.concurrent.RecursiveTask;


    public class ForkJoinPoolDemo {


    public static void main(String[] args) throws InterruptedException, ExecutionException {

    int arr[] = new int[100];

    Random random = new Random();

    int total = 0;

    // 初始化100個數字元素

    for (int i = 0; i < arr.length; i++) {

    int temp = random.nextInt(100);

    // 對數組元素賦值,并將數組元素的值添加到total總和中

    total += (arr[i] = temp);

    }

    System.out.println("初始化時的總和=" + total);

    // 創建包含Runtime.getRuntime().availableProcessors()返回值作為個數的并行線程的ForkJoinPool

    ForkJoinPool forkJoinPool = new ForkJoinPool();

    // 提交可分解的PrintTask任務

    Future<Integer> future = forkJoinPool.submit(new SumTaskDemo(arr, 0,

    arr.length));

    System.out.println("計算出來的總和=" + future.get());

    // 關閉線程池

    forkJoinPool.shutdown();

    }

    }


    // RecursiveTask為ForkJoinTask的抽象子類,有返回值的任務

    class SumTaskDemo extends RecursiveTask<Integer> {


    private static final long serialVersionUID = 4033241174438751063L;

    // 每個"小任務"最多只打印20個數

    private static final int MAX = 20;

    private int arr[];

    private int start;

    private int end;


    SumTaskDemo(int arr[], int start, int end) {

    this.arr = arr;

    this.start = start;

    this.end = end;

    }


    @Override

    protected Integer compute() {

    int sum = 0;

    // 當end-start的值小于MAX時候,開始打印

    if ((end - start) <= MAX) {

    for (int i = start; i < end; i++) {

    sum += arr[i];

    }

    return sum;

    } else {

    System.err.println("=====任務分解======");

    // 將大任務分解成兩個小任務

    int middle = (start + end) >>>1;

    SumTaskDemo left = new SumTaskDemo(arr, start, middle);

    SumTaskDemo right = new SumTaskDemo(arr, middle, end);

    // 并行執行兩個小任務

    left.fork();

    right.fork();

    // 把兩個小任務累加的結果合并起來

    return left.join() + right.join();

    }

    }

    }
    例子二:

    package demo.thread.fork;


    import java.util.Random;

    import java.util.concurrent.ForkJoinPool;

    import java.util.concurrent.RecursiveAction;

    import java.util.concurrent.TimeUnit;


    /**

     * @author lin

     *

     */

    public class ForkJoinPoolDemo2 {

    public static void main(String[] args) throws Exception {

    // 創建一個支持分解任務的線程池ForkJoinPool

    ForkJoinPool pool = new ForkJoinPool(4);

    myTask task = new myTask(60);


    pool.submit(task);

    pool.awaitTermination(10, TimeUnit.SECONDS);// 等待20s,觀察結果

    pool.shutdown();

    }


    }


    /**

     * 定義一個可分解的的任務類,繼承了RecursiveAction抽象類 必須實現它的compute方法

     */

    class myTask extends RecursiveAction {


    private static final long serialVersionUID = 1L;

    // 定義一個分解任務的閾值——50,即一個任務最多承擔50個工作量

    int THRESHOLD = 20;

    // 任務量

    int task_Num = 0;


    myTask(int Num) {

    this.task_Num = Num;

    }


    @Override

    protected void compute() {

    if (task_Num <= THRESHOLD) {

    System.out.println(Thread.currentThread().getName() + "承擔了"

    + task_Num + "份工作");

    /*try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }*/

    } else {

    // 隨機解成兩個任務

    Random m = new Random();

    int x = m.nextInt(50);

    myTask left = new myTask(x);

    myTask right = new myTask(task_Num - x);


    left.fork();

    right.fork();

    }

    }

    }






    posted on 2016-12-21 22:37 fly 閱讀(259) 評論(0)  編輯  收藏 所屬分類: java學習
    主站蜘蛛池模板: 免费影院未满十八勿进网站| 99久久精品免费视频| 青青草国产免费久久久下载| 亚洲自偷自拍另类图片二区| 亚洲免费视频在线观看| 亚洲天堂视频在线观看| 91老湿机福利免费体验| 亚洲另类春色校园小说| 一个人免费观看在线视频www| 亚洲熟妇AV一区二区三区宅男| 女人张开腿等男人桶免费视频| 午夜亚洲国产理论片二级港台二级 | 亚洲日本一区二区三区| 免费国产污网站在线观看15| 亚洲国产精品xo在线观看| 无人在线直播免费观看| 亚洲欧美日韩自偷自拍| 亚洲av午夜精品一区二区三区| 久久国产精品免费一区二区三区 | 亚洲视频免费观看| 在线观看视频免费完整版| 亚洲av无码日韩av无码网站冲 | 久久免费公开视频| 亚洲熟妇无码爱v在线观看| 日韩精品视频免费观看| 亚洲免费一区二区| 91在线亚洲精品专区| 成年人视频在线观看免费| 乱爱性全过程免费视频| 久久精品国产精品亚洲毛片| av无码免费一区二区三区| 美女免费视频一区二区| 亚洲Av无码精品色午夜| 岛国片在线免费观看| 中文字幕免费在线看线人动作大片| 亚洲午夜久久影院| 凹凸精品视频分类国产品免费| 久久九九全国免费| 亚洲AV色无码乱码在线观看| 久久久久久a亚洲欧洲aⅴ| 毛片免费vip会员在线看|