中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java J.U.C中ForkJoin的使用分析

發布時間:2021-10-21 09:31:00 來源:億速云 閱讀:150 作者:柒染 欄目:大數據

本篇文章給大家分享的是有關java J.U.C中ForkJoin的使用分析,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

ForkJoin框架是Java7提供的一個用于并行執行任務的框架,是一個把大任務分割成若干個小任務,最終匯總每個小任務結果后得到大任務結果的框架。

與MapReduce思想非常類似。從字面意思上看,Fork就是把一個大任務切割成若干個子任務并行執行,Join就是合并這些子任務的執行結果,最后得到大任務的結果。主要采用工作竊取算法。

    工作竊取算法是指某個線程從其他隊列里竊取任務來執行。下面是工作竊取的流程圖:

java J.U.C中ForkJoin的使用分析

為什么要使用工作竊取算法?

    加入我們需要做一個比較大的任務,我們可以把這個任務分割成若干個互不依賴的子任務,為了減少線程間的競爭,于是把這些子任務分別放到不同的隊列里,為每個隊列創建一個單獨的線程來執行隊列里面的任務,線程和隊列一一對應。比如A線程負責處理A隊列里面的任務,但是有些線程會先把自己的隊列里面的任務干完,而其他線程還有對應的任務等待處理,干完活的線程就會幫其他線程干活,于是就會去其他線程的隊列里竊取一個任務來執行,這時他們會訪問同一個隊列,所以為了減少竊取任務線程與被竊取任務線程之間的競爭,通常會使用雙端隊列,被竊取任務的線程永遠從雙端隊列的頭部拿任務執行,而竊取任務的線程永遠從雙端隊列的尾部拿任務執行。這種優點就是充分利用線程進行并行計算,減少了線程間的競爭,缺點是在某些情況下還是存在競爭(比如在雙端隊列只有一個任務時),同時也消耗了更多的系統資源(比如創建了多個線程和多個雙端隊列)。

    對于ForkJoin框架而言,當一個任務正在等待他使用ForkJoin操作創建的子任務結束時,執行這個任務的工作線程查找其他未被執行的任務,并開始他的執行,通過這種方式,線程充分利用他的運行時間來提高應用程序的性能,為了實現這個目標ForkJoin框架執行的任務有一些局限性。

局限性

  • 任務只能使用Fork和Join操作來作為同步機制,如果使用了其他同步機制,那他們在同步操作時工作線程就不能執行其他任務了。比如在forkjoin框架中使任務進入sleep,在睡眠期間內正在執行這個任務的工作線程將不會執行其他任務了。

  • 我們所拆分的任務不應該去執行IO操作。例如讀寫數據文件

  • 任務不能拋出檢查異常。必須通過必要的代碼來處理他們

ForkJoin框架的核心是兩個類:ForkJoinPool和ForkJoinTask。ForkJoinPool負責做實現(包括工作竊取算法)他管理工作線程提供任務的狀態以及他們的執行信息。而ForkJoinTask則主要提供在任務中執行Fork和Join操作的機制。

@Slf4j
public class ForkJoinTaskExample extends RecursiveTask<Integer> {

    public static final int threshold = 2;
    private int start;
    private int end;

    public ForkJoinTaskExample(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        int sum = 0;
        //如果任務足夠小就計算任務
        boolean canCompute = (end - start) <= threshold;
        if (canCompute) {
            for (int i = start; i <= end; i++) {
                sum += i;
            }
        } else {
            // 如果任務大于閾值,就分裂成兩個子任務計算
            int middle = (start + end) / 2;
            ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);
            ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end);

            // 執行子任務
            leftTask.fork();
            rightTask.fork();

            //等待任務執行結束合并其結果
            int leftResult = leftTask.join();
            int rightResult = rightTask.join();

            // 合并子任務
            sum = leftResult + rightResult;
        }
        return sum;
    }

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

        //生成一個計算任務,計算1+2+3+4...+100
        ForkJoinTaskExample taskExample = new ForkJoinTaskExample(1, 100);
        Future<Integer> result = forkJoinPool.submit(taskExample);
        try{
            log.info("result:{}", result.get());
        } catch (InterruptedException e) {
            log.error("exception", e);
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

以上就是java J.U.C中ForkJoin的使用分析,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

锦屏县| 仪陇县| 闻喜县| 财经| 柞水县| 阿拉善右旗| 香格里拉县| 泉州市| 闻喜县| 广安市| 郁南县| 富阳市| 鞍山市| 敦煌市| 黄梅县| 井陉县| 英德市| 家居| 盘山县| 喀什市| 镇赉县| 松江区| 隆回县| 灵武市| 房产| 额尔古纳市| 河池市| 石渠县| 库尔勒市| 隆安县| 宁南县| 贵阳市| 临邑县| 双柏县| 商丘市| 珠海市| 明溪县| 军事| 云阳县| 高要市| 讷河市|