1. 程式人生 > >Java 多執行緒中的任務分解機制-ForkJoinPool詳解

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)