Java 多執行緒中的任務分解機制-ForkJoinPool詳解
一、任務分解問題和ForkJoinPool簡介
在多執行緒併發程式設計中,有時候會遇到將大任務分解成小任務再併發執行的場景。Java 8新增的ForkJoinPool很好的支援了這個問題。
ForkJoinPool是一種支援任務分解的執行緒池,當提交給他的任務“過大”,他就會按照預先定義的規則將大任務分解成小任務,多執行緒併發執行。
一般要配合可分解任務介面ForkJoinTask來使用,ForkJoinTask有兩個實現它的抽象類:RecursiveAction和RecursiveTask,其區別是前者沒有返回值,後者有返回值。
下面通過具體程式碼,來示範兩個問題:(1)怎麼定義可分解的任務類 (2)如何使用ForkJoinPool
package com; import java.util.Random; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; import java.util.concurrent.TimeUnit; public class Main { /**定義一個可分解的的任務類,繼承了RecursiveAction抽象類 * 必須實現它的compute方法 */ public static class myTask extends RecursiveAction { private static final long serialVersionUID = 1L; //定義一個分解任務的閾值——50,即一個任務最多承擔50個工作量 int THRESHOLD=50; //任務量 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(); } } } public static void main(String[] args) throws Exception { //建立一個支援分解任務的執行緒池ForkJoinPool ForkJoinPool pool=new ForkJoinPool(); myTask task=new myTask(178); pool.submit(task); pool.awaitTermination(20, TimeUnit.SECONDS);//等待20s,觀察結果 pool.shutdown(); } }
執行結果如下:
ForkJoinPool-1-worker-1承擔了34份工作
ForkJoinPool-1-worker-2承擔了34份工作
ForkJoinPool-1-worker-3承擔了20份工作
ForkJoinPool-1-worker-0承擔了14份工作
ForkJoinPool-1-worker-0承擔了48份工作
ForkJoinPool-1-worker-3承擔了7份工作
ForkJoinPool-1-worker-2承擔了21份工作
二、總結
通過執行結果可以發現,ForkJoinPool支援開啟新執行緒執行被分解的任務,同時也會複用以前的老執行緒去承擔被分解的任務,具備執行緒池的通用屬性。
相關推薦
Java 多執行緒中的任務分解機制-ForkJoinPool詳解
一、任務分解問題和ForkJoinPool簡介 在多執行緒併發程式設計中,有時候會遇到將大任務分解成小任務再併發執行的場景。Java 8新增的ForkJoinPool很好的支援了這個問題
java多執行緒中等待/通知機制
一個執行緒做了修改物件值(或其他)操作,另一個執行緒感知到了變化,然後進行相應操作,整個過程開始於一個執行緒,最終執行又是另外一個執行緒。前者是生產者,後者是消費者,這種模式隔離了“做什麼”和“怎麼做”,實現了業務上的解耦。 其具體實現方式是執行緒A呼叫了物件O的wait(
java多執行緒的6種實現方式詳解
多執行緒的形式上實現方式主要有兩種,一種是繼承Thread類,一種是實現Runnable介面。本質上實現方式都是來實現執行緒任務,然後啟動執行緒執行執行緒任務(這裡的執行緒任務實際上就是run方法)。這裡所說的6種,實際上都是在以上兩種的基礎上的一些變形。 繼承
Java多執行緒之隔離技術ThreadLocal原始碼詳解
本篇文章是對ThreadLocal和InheritableThreadLocal,TransmittableThreadLocal的原理和原始碼進行深入分析,並舉例講解,其中前兩個是JDK自帶的。原理相對比較簡單,其解決了單執行緒環境和在單執行緒中又建立執行緒(
java多執行緒的6種實現方式詳解、執行緒池、定時器
多執行緒的形式上實現方式主要有兩種,一種是繼承Thread類,一種是實現Runnable介面。本質上實現方式都是來實現執行緒任務,然後啟動執行緒執行執行緒任務(這裡的執行緒任務實際上就是run方法)。這裡所說的6種,實際上都是在以上兩種的基礎上的一些變形。 繼承Thread
Java多執行緒中Synchronized簡介和Static Synchronized的區別
在進行Java開發時,多執行緒的開發是經常會使用的。首先會問一個小問題啊,在Java中有幾種方法可以建立一個執行緒? 我給的答案是3種。(如果還有其他的請留言告訴我哈。) 1、建立直接繼承自Thread類建立執行緒子類。 步驟如下:a 定義一個子類,同時
java多執行緒5.任務執行
將應用程式的工作分解到多個任務中,可以簡化程式的組織結構,提供一種自然的事務邊界來優化錯誤恢復過程,並提供一種自然的並行工作結構來提升併發性 理想情況下,能找出清晰的任務邊界,各個任務之間是相互獨立的,任務不依賴於其他任務的狀態、結果或邊界效應。 在正常的負載下,伺服器應用程式應該同時表現出良好
多執行緒中的訊號機制--sigwait 函式
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
java多執行緒中的異常處理
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
java多執行緒中顯式鎖的輪詢檢測策略
顯式鎖簡介 java5.0之前,在協調對共享物件的訪問時可以使用的機制只有synchronized和volatile,java5.0增加了一種新的機制:ReentrantLock。 鎖像synchronized同步塊一樣,是一種執行緒同步機制,與synchronized不同的是ReentrantLock提
Java多執行緒中注入Spring的Bean-使用靜態方法直接取的容器中的spring物件
目前認為比較好的解決方案。 1,工具類 public class SpringApplicationContextHolder implements ApplicationContextAware { private static ApplicationContext context
java多執行緒之等待喚醒機制(wait-notify)
wait()、notify()、notifyAll()方法 Object類裡面提供了這幾個方法: wait():讓當前執行緒處於等待(阻塞狀態),直到其他執行緒呼叫此物件的notify()或noti
白話理解java多執行緒中join()方法
join字面意思是加入,我理解為插隊. 舉例:媽媽在炒菜,發現沒喲醬油了,讓兒子去打醬油,兒子打完醬油,媽媽炒完菜,全家一起吃 package cn.yh.thread01; /** * *
Java多執行緒中volatile的場景應用
一、場景簡述 筆者在看多執行緒通訊相關問題時,不使用等待/通知機制實現多執行緒通訊的時候,發現b執行緒沒有與a執行緒發生正常通訊。 二、場景實現 如下是未發生正常通訊的程式碼 1、MyList類 package waitnotify; import java.ut
java 多執行緒等待、喚醒機制例項
例子: 1、實體類 public class Student { String name; int age; boolean flag = false; // 表示沒有值 } 2、執行緒1 public class SetThread impleme
java多執行緒處理任務
最近用到使用多執行緒處理給使用者傳送站內訊息的問題,想到使用java自帶的執行緒池進行處理這個問題,具體如下: 定義一個執行緒: package com.qlwb.util; import o
ArrayList在Java多執行緒中的應用
ArrayList是非執行緒安全的。 問題描述 開發中,存在這樣的業務邏輯,類似倒金字塔結構,下層資料需要基於上層的資料進行邏輯計算。設計思路是:定義一個全域性變數upLayerList,來儲存上一層的資料。每一層計算僅需要知道upLayerLi
Java多執行緒16:中斷機制
概述 之前講解Thread類中方法的時候,interrupt()、interrupted()、isInterrupted()三個方法沒有講得很清楚,只是提了一下。現在把這三個方法同一放到這裡來講,因為這三個方法都涉及到多執行緒的一個知識點--
Java多執行緒中start()和run()的區別
Java的執行緒是通過java.lang.Thread類來實現的。VM啟動時會有一個由主方法所定義的執行緒。可以通過建立Thread的例項來建立新的執行緒。每個執行緒都是通過某個特定Thread物件所對應的方法run()來完成其操作的,方法run()稱為執行緒體。通過呼叫Thread類的start(
java多執行緒中的sleep()、wait()、notify()和物件鎖的關係
1、sleep()不釋放物件鎖。 2、wait()釋放物件鎖。 3、notify()不釋放物件鎖。 (1)、notify釋放鎖嗎?不要誤導別人。notifty()只是喚醒此物件監視器上等待的單個執行緒,直到當前執行緒釋放此物件上的鎖,才有可能繼續執行被喚醒的執行緒。 (2)