Java并发Fork Join池原理和使用
ForkJoinPool函数是Java中非常适合执行递归循环的线程池。它在Java 7导入,类似于Executor framework,但是有一个不同点,ForkjoinPool是以一种递归方式运行,Executor框架是将任务划分为一段段提交给工作线程,而ForkJoinPool会将一个大任务划分为小任务,这些小任务会将它们再次划分为子任务,直到每个子任务是原子的或者不可再分,这样它就以一种递归方式运行。
Fork: 将大任务划分为小任务,比如Task 1.1划分为Task 1.1.1和Task1.1.2
Join:从直接子任务获得结果,比如Task 1.1从Task 1.1.1和Task 1.1.2获得结果
Fork-Join池快于Executor服务。
下面列举一个案例,我们需要在排序数组中搜索一个元素,我们使用二叉树搜索算法:
1. 首先将数组划分,找到数组的中间元素
2.检查被搜索元素是否等于中间元素,如果是,然后返回这个元素,作为在这个数组获得了结果。
3.如果这个元素小于中间元素,我们创建一个子任务,在这个子任务,我们对数组左边一半进行搜索
4.如果元素大于中间元素,然后我们创建一个子任务,在这个子任务,我们对数组右边一半进行搜索。
5.如果目标元素没有发现,继续重复4和5
6.如果数组大小是1,唯一元素不等于要发现的元素,返回没有发现。
import java.util.concurrent.RecursiveTask;
publicclassForkJoinSearcherextends RecursiveTask<Boolean>{
int[] arr;
int searchableElement;
ForkJoinSearcher(int[] arr,int search)
{
this.arr = arr;
this.searchableElement=search;
}
@Override
protected Boolean compute() {
int mid=( 0 + arr.length)/2;
System.out.println(Thread.currentThread().getName() + " says : After splliting the arry length is :: "+ arr.length + " Midpoint is " + mid);
if(arr[mid]=searchableElement)
{
System.out.println(" FOUND !!!!!!!!!");
return true;
}
elseif(mid=1 || mid == arr.length)
{
System.out.println("NOT FOUND !!!!!!!!!");
returnfalse;
}
elseif(searchableElement < arr[mid])
{
System.out.println(Thread.currentThread().getName() + " says :: Doing Left-search");
int[] left = Arrays.copyOfRange(arr, 0, mid);
ForkJoinSearcher forkTask = new ForkJoinSearcher(left,searchableElement);
forkTask.fork();
return forkTask.join();
}
elseif(searchableElement > arr[mid])
{
System.out.println(Thread.currentThread().getName() + " says :: Doing Right-search");
int[] right = Arrays.copyOfRange(arr, mid, arr.length);
ForkJoinSearcher forkTask = new ForkJoinSearcher(right,searchableElement);
forkTask.fork();
return forkTask.join();
}
returnfalse;
}
}
package com.example.concurrency;
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
publicclass BinarySearch {
int[] arr = newint[100];
public BinarySearch()
{
init();
}
privatevoid init()
{
for(int ; i<arr.length;i++)
{
arr[i];
}
Arrays.sort(arr);
}
publicvoid createForJoinPool(int search)
{
ForkJoinPool forkJoinPool = new ForkJoinPool(50);
ForkJoinSearcher searcher = new ForkJoinSearcher(this.arr,search);
Boolean status = forkJoinPool.invoke(searcher);
System.out.println(" Element ::" + search +" has been found in array? :: " + status );
}
publicstaticvoid main(String[] args) {
BinarySearch search = new BinarySearch();
search.createForJoinPool(10);
System.out.println("**********************");
search.createForJoinPool(104);
}
}
输出:
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 100 Midpoint is 50
ForkJoinPool-1-worker-57 says :: Doing Left-search
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 50 Midpoint is 25
ForkJoinPool-1-worker-57 says :: Doing Left-search
ForkJoinPool-1-worker-50 says : After splliting the arry length is :: 25 Midpoint is 12
ForkJoinPool-1-worker-50 says :: Doing Left-search
ForkJoinPool-1-worker-57 says : After splliting the arry length is :: 12 Midpoint is 6
ForkJoinPool-1-worker-57 says :: Doing Right-search
ForkJoinPool-1-worker-50 says : After splliting the arry length is :: 6 Midpoint is 3
ForkJoinPool-1-worker-50 says :: Doing Right-search
ForkJoinPool-1-worker-43 says : After splliting the arry length is :: 3 Midpoint is 1
FOUND !!!!!!!!!
Element ::10 has been found in array? :: true
**********************
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 100 Midpoint is 50
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 50 Midpoint is 25
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-50 says : After splliting the arry length is :: 25 Midpoint is 12
ForkJoinPool-2-worker-50 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 13 Midpoint is 6
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-50 says : After splliting the arry length is :: 7 Midpoint is 3
ForkJoinPool-2-worker-50 says :: Doing Right-search
ForkJoinPool-2-worker-57 says : After splliting the arry length is :: 4 Midpoint is 2
ForkJoinPool-2-worker-57 says :: Doing Right-search
ForkJoinPool-2-worker-43 says : After splliting the arry length is :: 2 Midpoint is 1
NOT FOUND !!!!!!!!!
Element ::104 has been found in array? :: false