I wonder would it be better to call get after we return from the executeTask ?  This way all the combiners can run in parallel.  The way this is currently each thread would block on the ExecutorService thread, in which case we could just run in this thread instead.  Also then the Set doesn't need to be synchronized, but you need a collection to hold the Futures.