Threads, which have always been an integral part of Java, have their limits: You cannot start more than a few thousand without jeopardizing system stability. For highly scalable applications, we had to resort to asynchronous programming. But asynchronous code is difficult to write, read and debug.
For years, a pioneering solution was being worked on within Project Loom: With almost 100,000 changed lines of code, the final version of virtual threads finally appeared in Java 21.
These require orders of magnitude fewer resources than conventional threads, especially for blocking operations. Instead of thousands, we now have millions of threads at our disposal. This allows us to write highly scalable applications in the traditional thread-per-request style that are easier to maintain, test, and debug than asynchronous applications.
Using an example application, I will take you from the limitations of classic concurrent programming to asynchronous approaches and the possible applications and functionality of virtual threads. With a final overview of limitations and potential pitfalls, as well as some tips on migrating existing applications, you will be well-equipped to use virtual threads in your daily work.