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

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

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

    聶永的博客

    記錄工作/學習的點點滴滴。

    Fork/Join模式(JSR166y)手記之Fork/Join模式實現淺析1

    對Fork/Join的個人理解要點:
    • fork/join將大的任務分割小的任務,直到小的任務可以使用最簡單、直接或者同步的方式處理。
    • 最小的任務將無法分解
    • 每一個任務不是線程的實例
    • 每一個工作線程將是一個隱式的線程實例
    • 每一個工作線程都會維護自身的一個雙向隊列(支持FIFO/LIFO);在任務產生的子任務,會被push進當前工作線程所維護deque隊列中,進入隊列頭部。
    • 當一個工作線程的雙向隊列中暫無任務時,它會從隨機的工作線程的雙向隊列的尾部獲取一個入隊最久的子任務(稱之為竊取),take()方式獲取,先進先出的規則(FIFO)。
    • 當一個工作線程遇到一個join的操作,假如可能的話,它會處理其他的任務,直到目標任務被通知需要處理掉。
    • 當一個工作者線程沒有任務可以處理,并且不能從其他工作者線程中竊取的時,它會后退(通過yields,sleeps,或者優先級的調整),稍后重試,直到所有工作線程都會處于空閑狀態,所有線程都會阻塞,等到另外的任務在頂層被調用。
    Brian Goetz 認為"使用傳統的線程池來實現 fork-join 也具有挑戰性,因為 fork-join任務將線程生命周期的大部分時間花費在等待其他任務上。這種行為會造成線程饑餓死鎖(thread starvation deadlock),除非小心選擇參數以限制創建的任務數量,或者池本身非常大。傳統的線程池是為相互獨立的任務設計的,而且設計中也考慮了潛在的阻塞、粗粒度任務 — fork-join 解決方案不會產生這兩種情況。對于傳統線程池的細粒度任務,也存在所有工作線程共享的任務隊列發生爭用的情況。"
    下面談一談工作竊取(work stealing)。在Fork/Join中,工作竊取采用了一個被當做棧(Stack)使用的雙端隊列WorkQueue。雙端隊列WorkQueue,支持在兩端插入和移除元素,和單獨的隊列(Queue)相比,多了一端。在Fork/Join中工作線程中被當做棧(Stack)來使用,在頭部push插入數據,pop獲取數。而尾部,可以供需要竊取的工作線程(take()方法)使用。與單向隊列相比,減少爭用,可以提高性能。
    WorkQueue的定義:
    static final class WorkQueue {
    ......
    }
    它既沒有繼承自Deque又沒有繼承Queue接口,而是自己獨立寫了一個雙端隊列,數組實現。很顯然,數組的讀取性能要強于鏈表。
    看一下ForkJoinPool的默認構造函數:
    public ForkJoinPool() {
    this(Runtime.getRuntime().availableProcessors(),
    defaultForkJoinWorkerThreadFactory, null, false);
    }

    public static interface ForkJoinWorkerThreadFactory {
    public ForkJoinWorkerThread newThread(ForkJoinPool pool);
    }

    static class DefaultForkJoinWorkerThreadFactory
    implements ForkJoinWorkerThreadFactory {
    public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
    return new ForkJoinWorkerThread(pool);
    }
    }
    在ForkJoinPool代碼初始化時,默認情況下:
    defaultForkJoinWorkerThreadFactory =
    new DefaultForkJoinWorkerThreadFactory();
    默認情況下,根據當前CPU的數量建立一個ForkJoinWorkerThreadFactory工廠,CPU數量個ForkJoinWorkerThread工作線程。
    仔細看一下ForkJoinWorkerThread代碼,工作線程繼承自Thread:

    很顯然,onStart 和 onTermination為鉤子函數,可以被重寫,但,需要構造一個新的ForkJoinPool.ForkJoinWorkerThreadFactory來配合使用。比如:
    public static void main(String[] args) {
    ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
    @Override
    public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
    return new CustomedForkJoinWorkerThread(pool);
    }
    };

    ForkJoinPool joinPool = new ForkJoinPool(Runtime.getRuntime()
    .availableProcessors(), factory, null, false);
    // some code here ...
    }

    private static final class CustomedForkJoinWorkerThread extends
    ForkJoinWorkerThread {
    protected CustomedForkJoinWorkerThread(ForkJoinPool pool) {
    super(pool);
    }

    @Override
    protected void onStart() {
    super.onStart();

    System.out.println("準備初始化資源...");
    }

    @Override
    protected void onTermination(Throwable exception) {
    System.out.println("開始清理資源...");

    super.onTermination(exception);
    }
    }
    接著看一下pool.runWorker(this)方法:
    final void runWorker(ForkJoinWorkerThread wt) {
    WorkQueue w = wt.workQueue;
    w.growArray(false);
    w.seed = hashId(Thread.currentThread().getId());

    do {} while (w.runTask(scan(w)));
    }
    初始化隊列,設置其seed為當前線程ID的哈希值。然后循環執行,當沒有任務可獲取,自然就退出了。而scan()很復雜,大概功能,從當前隊列中獲取元素,當前隊列為空時,從其他工作線程所持有的隊列中竊取一個。都沒有時,只能返回null,進而阻止線程活動。
    嗯,有時間會再深入WorkQueue隊列一些。
      
      
    參考資料:
    1. Java 理論與實踐: 應用 fork-join 框架
    2. JDK 7 中的Fork/Join 模式

    3. Doug Lea:A Java Fork/Join Framework

    posted on 2012-02-08 21:35 nieyong 閱讀(1779) 評論(0)  編輯  收藏 所屬分類: Java

    公告

    所有文章皆為原創,若轉載請標明出處,謝謝~

    新浪微博,歡迎關注:

    導航

    <2012年2月>
    2930311234
    567891011
    12131415161718
    19202122232425
    26272829123
    45678910

    統計

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲精品电影天堂网| 亚洲爆乳无码一区二区三区| 亚洲伊人久久大香线蕉啊| 久久久久免费看成人影片| 久久综合九九亚洲一区| 国产好大好硬好爽免费不卡| 亚洲综合无码精品一区二区三区| 成人免费网站视频www| 免费又黄又爽的视频| 四虎影视永久在线精品免费| 亚洲国产小视频精品久久久三级| 日本一区二区在线免费观看| 亚洲AV无码一区二区三区在线观看| 特级毛片A级毛片免费播放| 国产日产亚洲系列最新| 免费无码H肉动漫在线观看麻豆| 亚洲av无码精品网站| 亚洲黄色免费观看| 国产成人精品日本亚洲专区6| 日本xxwwxxww在线视频免费| 全黄A免费一级毛片| 亚洲AV综合色区无码一区爱AV| 成人黄网站片免费视频| 337p日本欧洲亚洲大胆精品555588| 无码乱肉视频免费大全合集 | 亚洲色婷婷综合久久| 免费无码又爽又刺激网站| 亚洲天堂福利视频| 国产网站在线免费观看| 99在线视频免费观看| 亚洲色图校园春色| 国产大片线上免费看| 久久免费线看线看| 天堂亚洲国产中文在线| 亚洲不卡AV影片在线播放| 最新国产乱人伦偷精品免费网站| 亚洲图片激情小说| 国产L精品国产亚洲区久久 | 国产精品免费αv视频| 亚洲国产高清视频| 日韩电影免费在线观看视频|