Monday, 13 July 2026

Using a Thread Factory to create Virtual Threads in Java

  

In Java, virtual threads make it much easier to write scalable applications that handle many tasks at the same time. But as we saw earlier, when using the builder pattern (Thread.ofVirtual()), the builder itself is not thread safe. This means if multiple parts of your program try to use the same builder at the same time, unexpected issues can occur.

 

To solve this, Java provides a Thread Factory. A factory is thread safe and can safely be shared across different parts of your program. This makes it a more reliable way to create virtual threads, especially in larger applications.

 

Example

ThreadFactory factory = Thread.ofVirtual().name("user-thread-", 0).factory();

// Create new threads using the factory
Thread t1 = factory.newThread(VirtualThreadExample3::handleUserRequest);
Thread t2 = factory.newThread(VirtualThreadExample3::handleUserRequest);

Here:

·      We create a factory using .factory(). The threads created by this factory will automatically get the prefix user-thread-.

·      Each call to factory.newThread(...) gives us a new virtual thread.

 

Find the below working Application.

 

VirtualThreadFactoryDemo1.java

package com.sample.app.virtual.threads.creation;

import java.util.concurrent.ThreadFactory;

public class VirtualThreadFactoryDemo1 {
        static void handleUserRequest() {
                try {
                        Thread.sleep(2000); // simulate work
                        System.out.println("Handled by: " + Thread.currentThread());
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
        }

        public static void main(String[] args) throws InterruptedException {
                // Create a thread factory with a custom name prefix
                ThreadFactory factory = Thread.ofVirtual().name("user-thread-", 0).factory();

                // Create new threads using the factory
                Thread t1 = factory.newThread(VirtualThreadFactoryDemo1::handleUserRequest);
                Thread t2 = factory.newThread(VirtualThreadFactoryDemo1::handleUserRequest);

                // Start the threads
                t1.start();
                t2.start();

                // Wait for them to finish
                t1.join();
                t2.join();
        }
}

   

Output

 

Handled by: VirtualThread[#27,user-thread-1]/runnable@ForkJoinPool-1-worker-2
Handled by: VirtualThread[#26,user-thread-0]/runnable@ForkJoinPool-1-worker-1

   

Sharing the Factory Across Multiple Components

Suppose your program has different modules, and both need to create threads. Instead of creating new builders everywhere, you can share a single factory.

 

VirtualThreadFactoryDemo2.java

package com.sample.app.virtual.threads.creation;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class VirtualThreadFactoryDemo2 {
        static class ModuleA {
                private final ThreadFactory factory;

                ModuleA(ThreadFactory factory) {
                        this.factory = factory;
                }

                void process() {
                        Thread t = factory.newThread(() -> {
                                System.out.println("Module A running in " + Thread.currentThread());
                        });
                        t.start();
                }
        }

        static class ModuleB {
                private final ThreadFactory factory;

                ModuleB(ThreadFactory factory) {
                        this.factory = factory;
                }

                void process() {
                        Thread t = factory.newThread(() -> {
                                System.out.println("Module B running in " + Thread.currentThread());
                        });
                        t.start();
                }
        }

        public static void main(String[] args) throws InterruptedException {
                // One shared factory
                ThreadFactory factory = Thread.ofVirtual().name("shared-thread-", 0).factory();

                ModuleA moduleA = new ModuleA(factory);
                ModuleB moduleB = new ModuleB(factory);

                moduleA.process();
                moduleB.process();
                
                // Some delay to let the virtual threads finish execution
                TimeUnit.SECONDS.sleep(1);
        }

}

Output

Module B running in VirtualThread[#28,shared-thread-1]/runnable@ForkJoinPool-1-worker-2
Module A running in VirtualThread[#26,shared-thread-0]/runnable@ForkJoinPool-1-worker-1

 

Previous                                                    Next                                                    Home

No comments:

Post a Comment