[concurrency-interest] Java Fork/Join Framework

Thomas Hawtin tackline at tackline.plus.com
Mon May 7 12:01:47 EDT 2007


Doug Lea wrote:
> 
> Thomas Hawtin wrote:
>>
>>  * That's an awful lot of types. Wouldn't the effort spent of 
>> primitive support be better spent bullying the JVM people into 
>> optimise boxing? 
> 
> [...]
> 
> If we could teach everyone how to reliably write the kind
> of code illustrated in the sunOfSquares example in
> http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166ydocs/jsr166y/forkjoin/ForkJoinTask.html 
> 
> then we wouldn't need most of these. (Although we'd still want some
> for prewired utilities like sorting.)

Can't most of that be abstracted? With a minimum sequential size, using
a reducer shouldn't be a problem.

I was thinking a general method like:

public static <T> T split(
     ForkJoinPool pool, int len, int minSeq, SplitTask<T> split
)

And then the sumOfSquares example would become:

double static sumOfSquares(ForkJoinPool pool, final double[] array) {
    return split(pool, array.length, 1024, new SplitTask<Double>() {
            public Double slice(int lo, int hi) {
  	       double sum = 0;
	       for (int i = lo; i <= hi; ++i) {
	          sum += array[i] * array[i];
	       }
	       return sum;
            }
            public Double combine(Double a, Double b) {
                return a+b;
            }
        }
    );
}

(Looking a ListTasks.reduce, a combined Mapper and Reducer would 
simplify use a little.)

>>  * Why List instead of Collection or Iterable? 
> 
> Because parallel recursive divide and conquer requires
> being able quickly to find midpoints breaking problems
> in half. Arrays and (RandomAccess) Lists provide this.
> Others don't, so you'd waste so much time linearly scanning
> to break up problems that you'd lose speedups for all but
> the heaviest code bodies. With lists and arrays, you can
> get very impressive speedups on MPs for ordinary
> reasonably small code bodies (like sums of squares for example).

I was thinking it's easy enough to convert a slow Collection or Iterable
into a RandomAccess List, but then I guess it's easy enough for the
caller too.

>>  * I object to the static ForkJoinTask methods.
>>
> 
> Do you object to static Thread methods? They use the same
> pattern for the same reason -- all the work in all ForkJoinTask
> methods is actually done via your Thread.currentThread(),
> which is specialized to ForkJoinPool.Worker.

Methods like yield? They only make sense on the current thread. The only
one I see like that is ForkJoinTask.getLocalQueueSize.
ForkJoinPool.getPool (which would be currentPool in Thread's convention)
seems unnecessary.

Tom Hawtin



More information about the Concurrency-interest mailing list