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

 

Java学习专题