A concurrency problem can begin with an ordinary requirement: let two independent
operations make progress without forcing one to wait for the other. The requirement
is easy to state. Choosing among Thread, ExecutorService, Future,
CompletableFuture, locks, atomics, queues, and synchronizers is harder when they
look like competing answers to the same question.






