DEV Community

Cover image for Virtual Threads In Java
Jorge Tovar
Jorge Tovar

Posted on

Virtual Threads In Java

Virtual threads deliver what they promise: making concurrency easy to use.

The change is minimal, instead of classic ThreadPool you can use newVirtualThreadPerTaskExecutor. That's all!

Thanks to Java 19 is now possible to create high-throughput applications using a lightweight concurrency model (similar to coroutines in Kotlin). This would be accomplished via virtual threads.

Spring Boot already supports Java 19 but we have to be patient cause still in preview mode.

Demo Java

Blocking task

    public Integer call() throws InterruptedException {
        return number;
Enter fullscreen mode Exit fullscreen mode

Process 1_000 blocking task

    public void process(String threadPoolType) throws InterruptedException, ExecutionException {

        try (ExecutorService executor = executorService) {
            List<Task> tasks = IntStream.range(0, 1_000)

            long time = System.currentTimeMillis();

            List<Future<Integer>> futures = executor.invokeAll(tasks);

            long sum = 0;
            for (Future<Integer> future : futures) {
                sum += future.get();

            time = System.currentTimeMillis() - time;
  "Result = {} ThreadPool sum: {} in {} ms", threadPoolType, sum, time);
Enter fullscreen mode Exit fullscreen mode

Process with Loom & Classic ThreadPool task*

    public void run(String... args) throws Exception {
        ExecutorService loom = Executors.newVirtualThreadPerTaskExecutor();
        ExecutorService classic = Executors.newFixedThreadPool(100);
        VirtualThreads virtualThreads = new VirtualThreads(classic);
        virtualThreads = new VirtualThreads(loom);
Enter fullscreen mode Exit fullscreen mode


- : Started DemoApplication in 0.373 seconds (JVM running for 0.66)
- : Result = classic ThreadPool sum: 499500 in 10062 ms
- : Result = loom ThreadPool sum: 499500 in 1015 ms
Enter fullscreen mode Exit fullscreen mode

Demo Kotlin


    measureTimeMillis {
        runBlocking {
            repeat(1_000) { i ->
                launch {
    }.also {
        print("Result = Coroutines finished in $it ms")

Enter fullscreen mode Exit fullscreen mode


Result = Coroutines finished in 1064 ms
Enter fullscreen mode Exit fullscreen mode


Project Loom is a game changer for Java. It will allow developers to create high concurrent applications without changing the paradigm or making big changes to the current code.

Top comments (4)

elrubens profile image

Great article! I very much like short articles like this one that go to the point and teach something very quickly :)

Just one thing: In the Kotlin example, I would either remove it completely, or, for the sake of fairness I would write one example where the return integer of the async task is used in the total sum as in the Java example! (that is, not to compare the measured time which I don't think there will be much variation, but mainly to compare the code for both solutions) but just my opinion :)

cicirello profile image
Vincent A. Cicirello

Very nice minimal example to demonstrate difference with classic threads.

nermin_karapandzic profile image
Nermin Karapandzic

Nice, I didn't know loom was available with Java 19, I was actually waiting for it as well to make some tests and comparisons.

michaeltharrington profile image
Michael Tharrington

This cover image is just so fitting. 😀