Not familiar with .NET, virtual threads in Java are an alternative to async await in other languages. The approach Java took is similar to green threads in go.
TPL is a library to create Tasks and run them. They can be scheduled in different ways, on (native) thread pools for example. They are commonly used together with async/await. They are very similar to promises in JavaScript.
I read about the approach without async/await, but honestly I don’t really get it. Seems to be very dangerous to me, if you give up control about scheduling. But sure, async/await is completely viral and it is everywhere now. Most functions tend to be async.
> virtual threads in Java are an alternative to async await in other languages
Not really. Async/Await is mostly about syntax. Transform callback-hell into something that looks like linear code. The underlying threading model doesn't really matter for that.