Fork/Join 設計解析__Java

來源:互聯網
上載者:User

介紹:

Fork/Join並行是獲得良好的並行效能的最簡單高效的設計技術。他是分治(Divide-and-Conquer)演算法的的並行實現,它的典型應用形式:

Result solve(Problem problem) {  if (problem is small)directly solve problem  else {split problem into independent partsfork new subtasks to solve each partjoin all subtaskscompose result from subresults}}

fork操作啟動一個新的並行fork/join子任務,join操作則導致當前線程等待直到子任務執行完成。fork/join演算法,就像其它分治演算法一樣,幾乎經常是不斷的遞迴,重複劃分子任務——直到它們的規模小到能夠使用簡單、簡短的串列方法完成。


思想:

    1、分而治之,將大任務分解為小任務,再合并最終結果

    2、工作竊取調度策略

                     (1)每個worker線程利用它自己的調度隊列維護可執行任務。
        (2)隊列是雙端的,支援LIFO(last-in-first-out)也支援FIFO(first-in-first-out)。
        (3)一個任務fork的子任務,只會push到它所線上程的隊列。
        (4)背景工作執行緒使用LIFO通過pop處理它自己隊列中的線程。
        (5)當線程自己沒有待處理任務時,它嘗試去隨機讀取(竊取)一個worker線程的工作隊列任務(使用FIFO)。
        (6)當線程進入join操作,它開始處理其它線程的任務(自己的已經處理完了),直到目標任務完成(通過isDone方法)。因此,所有任務都無阻塞的完成了。

        (7)當一個背景工作執行緒沒有任務了,並且嘗試從其它線程處竊取也失敗了,它讓出資源(通過使用yields, sleeps或者其它優先順序調整)並且隨後會再次啟用,直到所有背景工作執行緒都空閑了——此時,它們都阻塞在等待另一個頂層線程的調用。


兩種介面:

    RecursiveTask: 帶傳回值,底層用的是Callable介面

    RecursiveAction:無傳回值,Runnable介面


ForkJoinPool源碼中重要欄位:

eventCount三種含義:   1、線程被掛起次數   2、小於零表示沒有被啟用狀態   3、標明為第幾個背景工作執行緒nextWait: 由於fork/join維護著一個掛起線程鏈,這個鏈是棧結構,本欄位就是遍曆掛起棧用的qlock: 起到鎖的作用top、base : 分別是儲存背景工作執行緒隊列的頭和尾poolIndex: 指的是背景工作執行緒在隊列中的下標


核心方法scan流程解析:

    


設計亮點:

    1、互幫互助的設計思路

    2、多欄位打包操作


範例程式碼: 完成累加運算

import java.util.ArrayList;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.ForkJoinTask;import java.util.concurrent.RecursiveTask;/** * @Author: Allen * @Description:    用ForkJoinPool實現累加操作 * @Date: Created in 12:42 2018/2/27 * @Modify By: */public class CountTask extends RecursiveTask<Long> {    private static final int THRESHOLD = 10000;    private long start;    private long end;    public CountTask(long start,long end){        this.start = start;        this.end = end;    }    @Override    protected Long compute() {        long sum = 0;        boolean canCompute = (end-start)<THRESHOLD;        if (canCompute) // 是否可以再分            for (long i = start; i <= end; i++) {                sum+=i;            }        else{            long step = (end+start)/100000;                    // 分成100個任務            ArrayList<CountTask> tasks = new ArrayList<>(); // 任務數組            long pos = step;    // 每個任務的大小            for (int i = 0; i < 100000; i++) {                long lastOne = pos+step;            // 根據任務大小獲得一個任務                if (lastOne > end) lastOne = end;   // 上限超出的話就設定上限                CountTask subTask = new CountTask(pos,lastOne); // 建立一個任務                System.out.println("new task inf : "+pos+"\t"+lastOne);                pos+=step+1;        // 更新下一個任務的初始位置                tasks.add(subTask); // 將任務都加入到任務數組中                subTask.fork();     // 執行任務            }            // 擷取累加值            for (CountTask t :                    tasks) {                sum+=t.join();            }        }        return sum;    }    public static void main(String[] args) {        ForkJoinPool forkJoinPool = new ForkJoinPool();     // 預設是用cpu的最大核心數去工作        CountTask task = new CountTask(0,200000000L);        ForkJoinTask<Long> result = forkJoinPool.submit(task);  // 提交一個任務        try {            long res = result.get();            System.out.println("sum= "+res);        }catch (Exception e){            e.printStackTrace();        }    }}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.