Асинхронное программирование обычно включает в себя некоторые виды взаимодействия задач. Различные виды асинхронного программирования обеспечивают разные виды взаимодействия задач.
ExecutorService выполняет представленные задачи, как только существует доступный процессор, то есть он предоставляет только простейшую форму асинхронного программирования, вообще без взаимодействия с задачей.
Реактивное программирование предоставляет каналы для обмена сообщениями с противодавлением, что является довольно продвинутым видом взаимодействия задач. Но под капотом он все еще использует ExecutorService.