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

Peter Levart peter.levart at gmail.com
Mon Apr 14 02:51:11 EDT 2014


On 04/14/2014 12:50 AM, Doug Lea wrote:
> Peter: Maybe you could post one of your examples as
> a sample test program.
>
> -Doug

Sure, here's an artificial example that provokes StackOverflowError in 
previous version (CVS:1.99):


import java.math.BigInteger;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;

public class FibonacciPrimes {

     static Future<Set<BigInteger>> fibonacciPrimes(
         CompletableFuture<BigInteger> f0,
         CompletableFuture<BigInteger> f1,
         int n) {
         if (n < 0) throw new IllegalArgumentException("n should be >= 0");

         Set<BigInteger> result = new ConcurrentSkipListSet<>();
         AtomicInteger c = new AtomicInteger(n + 1);
         CompletableFuture<Set<BigInteger>> future = new 
CompletableFuture<>();

         Consumer<BigInteger> addIfPrime = i -> {
             if (i.isProbablePrime(100)) result.add(i);
             if (c.decrementAndGet() == 0) future.complete(result);
         };

         f0.thenAcceptAsync(addIfPrime);
         if (n > 0) {
             f1.thenAcceptAsync(addIfPrime);
             for (int i = 2; i <= n; i++) {
                 f1 = f0.thenCombine(f0 = f1, BigInteger::add);
                 f1.thenAcceptAsync(addIfPrime);
             }
         }

         return future;
     }

     public static void main(String[] args) throws Exception {
         CompletableFuture<BigInteger> f0 = new CompletableFuture<>();
         CompletableFuture<BigInteger> f1 = new CompletableFuture<>();

         long t0 = System.currentTimeMillis();
         int n = 10000;
         Future<Set<BigInteger>> primes = fibonacciPrimes(f0, f1, n);

         f0.complete(BigInteger.ZERO);
         f1.complete(BigInteger.ONE);

         System.out.println("Primes among 1st " + (n + 1) + " Fibonacci 
numbers:");
         for (BigInteger prime : primes.get()) {
             System.out.println(prime);
         }
         System.out.println((System.currentTimeMillis() - t0) + " 
millis.");
     }
}


Regards, Peter



More information about the Concurrency-interest mailing list