It's about as painless as it gets when you aren't bottlenecked on number of actor like things. I never am because I eat the pain of not blocking rather than asking a framework to do it for me (or fail at it).
Java 8 has CompletableFuture so you don't need to leave the JDK anymore, but the javadoc makes my eyes bleed compared to Guava's ListenableFuture. I do like that CompletableFuture doesn't use synchronized internally.
The thing you have to aware of with async is backpressure. You have now decoupled thread pool exhaustion from task creation allowing unbounded memory usage. And once you allow backpressure you need to start thinking a little bit harder about deadlocks due to bounded queues.
Eliminating cycles, ignoring bounds where cycles exist, or allowing errors/shedding can help, but it's the kind of thing that keeps me up a night.
I haven't played with Guava, but I have used Otto a bit, and at one point wrote my own simple observer framework (which is slightly less work than implementing a Java Observer). As I wrote in the disclaimer, there are lots of ways of doing this. =)