Introduce the use of ForkJoinPool

ForkJoinPool is the thread pool provided by JDK 1.7. In order to solve the problem of unbalanced CPU load. For example, a large task is executed by one thread while other threads are idle.

 

ForkJoinTask represents a task. Among the subclasses of ForkJoinTask are RecursiveAction and RecursiveTask.
There is no result returned from recursive action; recursive task has a result returned.
Rewrite compute() of recursive action or recursive task to complete the calculation or split the task.

 

Call the fork() method of the ForkJoinTask to allow other idle threads to execute the ForkJoinTask;
Call the join() method of the ForkJoinTask to summarize the results of multiple small tasks.

 

No return value print task split
 

package constxiong.interview;
 
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;
 
/**
 * Test the use of the ForkJoinPool thread pool
 * @author ConstXiong
 * @date 2019-06-12 12:05:55
 */
public class TestForkJoinPool {
 
	public static void main(String[] args) throws Exception {
		testNoResultTask();//Test task execution with no return value of ForkJoinPool
	}
	
	/**
	 * Test task execution with no return value of ForkJoinPool
	 * @throws Exception
	 */
	public static void testNoResultTask() throws Exception {
		ForkJoinPool pool = new ForkJoinPool();
		pool.submit(new PrintTask(1, 200));
		pool.awaitTermination(2, TimeUnit.SECONDS);
		pool.shutdown();
	}
}
	
/**
 * Print task without return value
 * @author ConstXiong
 * @date 2019-06-12 12:07:02
 */
class PrintTask extends RecursiveAction {
	
	private static final long serialVersionUID = 1L;
	private static final int THRESHOLD = 49;
	private int start;
	private int end;
	
	public PrintTask(int start, int end) {
		super();
		this.start = start;
		this.end = end;
	}
	
 
	@Override
	protected void compute() {
		//When the end value is greater than the start value by 49, it is divided into two tasks according to the numerical range; otherwise, the value of the range will be printed directly
		if (end - start <THRESHOLD) {
			for (int i = start; i <= end; i++) {
				System.out.println(Thread.currentThread().getName() + ", i = " + i);
			}
		} else {
			int middle = (start + end) / 2;
			PrintTask firstTask = new PrintTask(start, middle);
			PrintTask secondTask = new PrintTask(middle + 1, end);
			firstTask.fork();
			secondTask.fork();
		}
	}
	
}

 

Split calculation tasks and merge results with return values

package constxiong.interview;
 
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;
 
/**
 * Test the use of the ForkJoinPool thread pool
 * @author ConstXiong
 * @date 2019-06-12 12:05:55
 */
public class TestForkJoinPool {
 
	public static void main(String[] args) throws Exception {
		testHasResultTask();//The test uses the task execution with return value of ForkJoinPool to merge the results. Calculate the sum of 1 to 200
	}
	
	/**
	 * The test uses the task execution with return value of ForkJoinPool to merge the results. Calculate the sum of 1 to 200
	 * @throws Exception
	 */
	public static void testHasResultTask() throws Exception {
		int result1 = 0;
		for (int i = 1; i <= 200; i++) {
			result1 += i;
		}
		System.out.println("Cycle calculation 1-200 Cumulative value:" + result1);
		
		ForkJoinPool pool = new ForkJoinPool();
		ForkJoinTask<Integer> task = pool.submit(new CalculateTask(1, 200));
		int result2 = task.get();
		System.out.println("Parallel computing 1-200 Cumulative value:" + result2);
		pool.awaitTermination(2, TimeUnit.SECONDS);
		pool.shutdown();
	}
	
}
 
/**
 * Calculation task with return value
 * @author ConstXiong
 * @date 2019-06-12 12:07:25
 */
class CalculateTask extends RecursiveTask<Integer> {
 
	private static final long serialVersionUID = 1L;
	private static final int THRESHOLD = 49;
	private int start;
	private int end;
	
	public CalculateTask(int start, int end) {
		super();
		this.start = start;
		this.end = end;
	}
 
	@Override
	protected Integer compute() {
		//When the end value is greater than the start value by 49, it is divided into two tasks according to the numerical range, and the accumulated value of the two tasks is summarized; otherwise, the accumulated value is calculated directly
		if (end - start <= THRESHOLD) {
			int result = 0;
			for (int i = start; i <= end; i++) {
				result += i;
			}
			return result;
		} else {
			int middle = (start + end) / 2;
			CalculateTask firstTask = new CalculateTask(start, middle);
			CalculateTask secondTask = new CalculateTask(middle + 1, end);
			firstTask.fork();
			secondTask.fork();
			return firstTask.join() + secondTask.join();
		}
	}
	
}


Original link
 

 

All resources are summarized in the public address.



 

Keywords: Programming Java JDK

Added by a1ias on Wed, 11 Dec 2019 20:26:36 +0200