The Loom scheduler does NOT guarantee resource starvation avoidance for high CPU usage. You need to Thread.yield.
I also thought of creating a mapping from synchronous code and rewriting it to a tree of LMAX disruptors. I ported a wait-free ringbuffer from C++ to Java today - it was written by Alexander Krizhanovsky[1]
In LMAX disruptor you split each IO request in half - you have a disruptor that enqueuing events events to request the IO and to pass the event on to a callback you enqueue the response on a different disruptor.
If a synchronous request handler has 27 lines it represents a tree of 27 disruptor threads independently scaled.
We can pipeline the request with 27 threads all in an event loop that pipeline each task × core count and without blocking the servicing thread or other work. So event loops without blocking! So CPU heavy tasks do not block other heavy CPU tasks and do not block the servicing thread and are not blocked by IO.
https://github.com/samsquire/ideas4#51-rewrite-synchronous-c...
[1]: https://www.linuxjournal.com/content/lock-free-multi-produce...