[concurrency-interest] Java 8 CompletableFuture.thenCombine() hangs

Doug Lea dl at cs.oswego.edu
Sun Apr 13 18:50:12 EDT 2014


Back to...

On 04/06/2014 05:40 PM, Doug Lea wrote:
> On 04/01/2014 07:16 PM, Dennis Sosnoski wrote:
>> I've run into a situation with CompletableFuture.thenCombine() hanging
>> ...
>
>>          for (int i = 1; i < n; i++) {
>>              last = CompletableFuture.supplyAsync(newLambda(i))
>> .thenCombine(last, Math::max);
>>          }
>>          return last.join();
>>      }
>
> Even though this code looks like a loop, it was evaluated recursively
> (across multiple threads) which can blow up default-sized runtime
> stacks even when n is 10000 or so.
>
> The StackOverflowError was correctly managed by one (or more)
> of the intermediate CompletableFutures in the long chain
> constructed.

Well, not necessarily. A StackOverflowError can occur at
any call, including, for CompletableFuture, internal
bookkeeping calls by unknown Executors. Considering
that CompletableFuture goes to great lengths to manage
other Errors and Exceptions, we ought to do the same here,
even for non-tail-recursive cases.


> By re-packing actions
> while processing dependent completions, we can isolate
> tail-recursive cases and loopify them. This generally works out
> better than moving them across lists, because doing so can
> reduce opportunities for other threads to help process them.

By further repacking actions, we can move completion lists
around even in non-tail recursive cases without practical
loss in potential parallelism, and, as it turns out, with
a small gain in average throughput. (For those interested,
the main change is for racing CFs to directly try to
complete rather than helping their sources do so, which
would not work if moved. This is a small change conceptually,
but leads to lots of diffs because the same idea is used
in different ways across functional forms.)

Updated sources at
 
http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/main/java/util/concurrent/CompletableFuture.java?view=log 


Also compiled into the jar at
    http://gee.cs.oswego.edu/dl/jsr166/dist/jsr166.jar
that you can run with -Xbootclasspath

Please try it out.

Thanks to Peter Levart for some further prodding on this.
Peter: Maybe you could post one of your examples as
a sample test program.

-Doug




More information about the Concurrency-interest mailing list