Project Loom makes Java in particular really nice, virtual threads can "block" without blocking the underlying OS thread. No callbacks at all, and you can even use Structured Concurrency to implement all sorts of Go- and Erlang-like patterns.

(I use it from Clojure, where it pairs great with the "thread" version of core.async (i.e. Go-style) channels.)