Right now whenever a listener is added to a Future, that listener might be executed by the caller or be the task thread. This can easily lead to deadlocks without reentrant locks.
So we should at least make it deterministic (i.e. have it always be executed by either the task thread or at least the same pool as the task thread).
The best solution though would be to make it like guava's ListenableFuture which always executes listeners in their own executor.