A Future only blocks when you call get() on it but unfortunately there is not much else you can do. CompletableFuture is a Future but adds all the methods (but way too many methods) you need to tell it what to do when it has a result. This is so much simpler in Scala.
Avoid get(), instead use thenAcceptAsync() / thenRunAsync() methods run in a different thread from the thread pool.