Java多線程——Fork/Join架構__Java

來源:互聯網
上載者:User

使用多線程技術,讓不同的任務在不同的線程中運行,可以提高CPU的利用率。然而只是僅僅通過任務來劃分,粒度還是有點大。當任務中有些任務運行所佔時間遠遠大於其它任務的時候,使用多線程並發所帶來的效果並不明顯。在這種情況下把耗時間長度的大任務劃分為耗時短的小任務,可以有效地緩解並發的瓶頸,最終把小任務的結果合并擷取完整的任務的結果。Fork/Join就可以很好地實現這種劃分任務最後合并的思路(你可以把它當做並發版的分治)。


一、ForkJoinTask & ForkJoinPool

1. ForkJoinTask<V>

擴充自Future,它代表的是比任務更加輕量級,細粒度的並發單元。它本身是一個抽象類別,這裡提兩個重要的抽象子類:RecursiveAction和RecursiveTask<V>,通過重寫它們的compute方法可以定義任務,要注意的是前者的compute是不帶傳回值的,而後者的是有傳回值的。

a. fork()方法允許ForkJoinTask任務非同步執行,也允許一個新的ForkJoinTask從存在的ForkJoinTask中被啟動。變種: invoke(), invokeAll()

b. 反過來, join()方法允許一個ForkJoinTask等待另一個ForkJoinTask執行完成。變種: get()


2. ForkJoinPool

繼承自AbstractExecutorService,用於調度ForkJoinTask。


3. 調度機制

一個主的ForkJoinTask被提交到ForkJoinPool之後開始執行。然後ForkJoinTask開始(通過fork()等方法)啟動它的子任務,並(通過get()等方法)等待它們完成。



二、使用Fork/Join架構

下面是最經典的Fork/Join架構的使用情境:

if task is small enough

execute the task

else

divide it into several smaller tasks

invoke all tasks

group results


例子:

import java.util.concurrent.ExecutionException;import java.util.concurrent.ForkJoinPool;import java.util.concurrent.RecursiveTask;import java.util.concurrent.TimeUnit;public class FJCount extends RecursiveTask {private String document[];private int start, end;private String word;FJCount (String _d[], int _s, int _e, String _w) {document = _d;start = _s;end = _e;word = _w;}@Overrideprotected Object compute() {int result = 0;if (end - start < 10) {result = count(document, start, end, word);} else {int mid = (start + end) / 2;FJCount task1 = new FJCount(document, start, mid, word);FJCount task2 = new FJCount(document, mid+1, end, word);invokeAll(task1, task2);try {result = (int)task1.get() + (int)task2.get();} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}return result;}int count(String []document, int start, int end, String word) {int counter = 0;for (int i = start; i <= end; ++i) {if (document[i] == word) {++counter;}}return counter;}public static void main(String ...arg) {String document[] = new String[100];for (int i = 0; i < 100; ++i) {if (i%10 == 0)document[i] = "Test";elsedocument[i] = " ";}FJCount test = new FJCount(document, 0, 99,"Test");ForkJoinPool pool = new ForkJoinPool();pool.execute(test);do {System.out.println("****************************");System.out.printf("Main: Paralleism: %d\n", pool.getParallelism());System.out.printf("Main: Active Threads: %d\n", pool.getActiveThreadCount());System.out.printf("Main: Task Count: %d\n", pool.getQueuedTaskCount());System.out.printf("Main: Steal Count: %d\n", pool.getStealCount());try {TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e){e.printStackTrace();}} while (!test.isDone());pool.shutdown();try {pool.awaitTermination(1,  TimeUnit.DAYS);}catch (InterruptedException e) {e.printStackTrace();}try {System.out.printf("Main: The word appears %d times in the document", test.get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}}


三、工作竊取

ForkJoinPool維護每個線程的工作清單,當某個任務完成時,它可以把掛在滿負荷線程上的任務重新安排到空閑線程上去。就好比兩個人搬磚,先搬完的回去幫另外那個人搬剩下的磚。這就是所謂的工作竊取,它解決了不同大小的任務之間的調度問題。工作竊取特性是ForkJoinPool和一些其它的ExecutorService的區別之一。


四、總結

Fork/Join通過把任務分割成更細粒度的單元,可以有效地減少瓶頸,提高CPU的使用率。當問題可以被分成很多可以平行處理的子問題的時候可以考慮使用Fork/Join。比如說Arrays的parallelSort方法就是通過Fork/Join來實現的。


Reference:

http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html

http://www.oracle.com/technetwork/articles/java/fork-join-422606.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinTask.html

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ForkJoinPool.html

《Java 7 Concurrency Cookbook》

《The Well-Grounded Java Developer》

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.