Java had a quite lousy implementation of green threads, that hurt performance more than enabled parallelism. (What isn't explainable by it being early, since there were earlier green threads implementation that didn't suck. Looks like it just wasn't a priority for Java developers.)
There's nothing anywhere restricting green threads to a single OS thread. Most modern runtimes will automatically multiplex the green threads into as many OS threads as your computer can run.
Java had a mixed model where it could use LWPs or kernel threads, and switched over around Solaris 8 because things like stat() were still blocking and had no async counterpart, so were difficult to deal with.
I dug up this fossil the other day, trying to get a fix from Sun for this very issue:
Is this solved in Go? A while back Go required programmers to use rate limiters, otherwise it would spawn unlimited kernel threads for blocking syscalls.
There's nothing anywhere restricting green threads to a single OS thread. Most modern runtimes will automatically multiplex the green threads into as many OS threads as your computer can run.