They are not - and do not claim to be preemptive. They claim they are "not cooperative", but even that doesn't mean what anyone else thinks it means.
This paragraph is the only one containing the word "preempt" in JEP 444:
"The scheduler does not currently implement time sharing for virtual threads. Time sharing is the forceful preemption of a thread that has consumed an allotted quantity of CPU time. While time sharing can be effective at reducing the latency of some tasks when there are a relatively small number of platform threads and CPU utilization is at 100%, it is not clear that time sharing would be as effective with a million virtual threads."
We were talking about n:m threading, especially with threads being blocking IO-aware, being able to automagically turning such a call to non-blocking. Java more than fits that description.
The original message you replied to said (mistakenly):
> adopt true goroutines
Goroutines are preemptive. The distinction between cooperative and non-cooperative concurrency is very significant - it is the difference between never having to think about the scheduler and always having to thinking about it when doing CPU intensive tasks.
This paragraph is the only one containing the word "preempt" in JEP 444:
"The scheduler does not currently implement time sharing for virtual threads. Time sharing is the forceful preemption of a thread that has consumed an allotted quantity of CPU time. While time sharing can be effective at reducing the latency of some tasks when there are a relatively small number of platform threads and CPU utilization is at 100%, it is not clear that time sharing would be as effective with a million virtual threads."
https://openjdk.org/jeps/444