Java Reference
In-Depth Information
It isn't possible to perform that algorithm efficiently using a ThreadPoolExecutor , because
a parent task must wait for its child tasks to complete. A thread inside a ThreadPoolExecut-
or cannot add another task to the queue and then wait for it to finish: once the thread is wait-
ing, it cannot be used to execute one of the subtasks. The ForkJoinPool , on the other hand,
allows its threads to create new tasks and then suspend their current task. While the task is
suspended, the thread can execute other pending tasks.
Let's take a simple example: say that we have an array of doubles, and the goal is to count
the number of values in the array that are less than 0.5. It's trivial simply to scan the array se-
quentially (and possibly advantageous, as we'll see later in this section)—but for now, it is
instructive to divide the array into subarrays and scan them in parallel (emulating the more
complex quicksort and other divide-and-conquer algorithms). Here's an outline of the code to
achieve that with a ForkJoinPool :
public
public class
class ForkJoinTest
ForkJoinTest {
private
private double
double [] d ;
private
private class
class ForkJoinTask
ForkJoinTask extends
extends RecursiveTask < Integer > {
private
private int
int first ;
private
private int
int last ;
public
public ForkJoinTask ( int
int first , int
int last ) {
this
this . first = first ;
this
this . last = last ;
}
protected
protected Integer compute () {
int
int subCount ;
iif ( last - first < 10 ) {
subCount = 0 ;
for
for ( int
int i = first ; i <= last ; i ++) {
iif ( d [ i ] < 0.5 )
subCount ++;
}
}
else
else {
int
int mid = ( first + last ) >>> 1 ;
ForkJoinTask left = new
new ForkJoinTask ( first , mid );
left . fork ();
ForkJoinTask right = new
new ForkJoinTask ( mid + 1 , last );
right . fork ();
subCount = left . join ();
Search WWH ::




Custom Search