1. Introduction
In this short tutorial, we’ll see an example of carrier thread in Java. We’ll see with an example that carrier threads work on different tasks in case of virtual threads.
2. Example of Platform thread working on tasks
In this example, we are creating and starting platform threads. We are using sleep()
method to demonstrate the I/O intensive task. Task
class represents the Java class.
Demo.java
public class Demo { public static void main(String[] args) throws InterruptedException { platformThreadDemo(); } private static void platformThreadDemo(){ for(int i=0; i< 20; i++){ int j = i; Thread.ofPlatform().name("Thread" + j).start(() -> Task.ioIntensiveTask(j)); } } }
Task.java
import java.time.Duration; public class Task { public static void ioIntensiveTask(int i) { try { System.out.println("starting i/o task " + i + " Current Thread: "+ Thread.currentThread()); Thread.sleep(Duration.ofSeconds(10l)); } catch (InterruptedException e) { throw new RuntimeException(e); } } }
Output
starting i/o task 17 Current Thread: Thread[#38,Thread17,5,main]
starting i/o task 0 Current Thread: Thread[#21,Thread0,5,main]
starting i/o task 1 Current Thread: Thread[#22,Thread1,5,main]
starting i/o task 19 Current Thread: Thread[#40,Thread19,5,main]
starting i/o task 5 Current Thread: Thread[#26,Thread5,5,main]
starting i/o task 6 Current Thread: Thread[#27,Thread6,5,main]
starting i/o task 8 Current Thread: Thread[#29,Thread8,5,main]
starting i/o task 7 Current Thread: Thread[#28,Thread7,5,main]
starting i/o task 11 Current Thread: Thread[#32,Thread11,5,main]
starting i/o task 9 Current Thread: Thread[#30,Thread9,5,main]
starting i/o task 16 Current Thread: Thread[#37,Thread16,5,main]
starting i/o task 13 Current Thread: Thread[#34,Thread13,5,main]
starting i/o task 15 Current Thread: Thread[#36,Thread15,5,main]
starting i/o task 12 Current Thread: Thread[#33,Thread12,5,main]
starting i/o task 18 Current Thread: Thread[#39,Thread18,5,main]
starting i/o task 10 Current Thread: Thread[#31,Thread10,5,main]
starting i/o task 2 Current Thread: Thread[#23,Thread2,5,main]
starting i/o task 3 Current Thread: Thread[#24,Thread3,5,main]
starting i/o task 4 Current Thread: Thread[#25,Thread4,5,main]
starting i/o task 14 Current Thread: Thread[#35,Thread14,5,main]
Observe that each platform is working on the specified task.
3. Example of Virtual thread
Now lets use the virtual threads for the same example. Change the way threads are created.
public class Demo { public static void main(String[] args) throws InterruptedException { platformThreadDemo(); Thread.currentThread().join(); } private static void platformThreadDemo(){ for(int i=0; i< 20; i++){ int j = i; Thread.ofVirtual().name("Thread" + j).start(() -> Task.ioIntensiveTask(j)); } } }
Output
starting i/o task 4 Current Thread: VirtualThread[#26,Thread4]/runnable@ForkJoinPool-1-worker-5
starting i/o task 1 Current Thread: VirtualThread[#23,Thread1]/runnable@ForkJoinPool-1-worker-2
starting i/o task 8 Current Thread: VirtualThread[#30,Thread8]/runnable@ForkJoinPool-1-worker-1
starting i/o task 13 Current Thread: VirtualThread[#35,Thread13]/runnable@ForkJoinPool-1-worker-3
starting i/o task 16 Current Thread: VirtualThread[#38,Thread16]/runnable@ForkJoinPool-1-worker-4
starting i/o task 5 Current Thread: VirtualThread[#27,Thread5]/runnable@ForkJoinPool-1-worker-6
starting i/o task 3 Current Thread: VirtualThread[#25,Thread3]/runnable@ForkJoinPool-1-worker-4
starting i/o task 2 Current Thread: VirtualThread[#24,Thread2]/runnable@ForkJoinPool-1-worker-3
starting i/o task 0 Current Thread: VirtualThread[#21,Thread0]/runnable@ForkJoinPool-1-worker-1
starting i/o task 6 Current Thread: VirtualThread[#28,Thread6]/runnable@ForkJoinPool-1-worker-3
starting i/o task 7 Current Thread: VirtualThread[#29,Thread7]/runnable@ForkJoinPool-1-worker-4
starting i/o task 9 Current Thread: VirtualThread[#31,Thread9]/runnable@ForkJoinPool-1-worker-3
starting i/o task 10 Current Thread: VirtualThread[#32,Thread10]/runnable@ForkJoinPool-1-worker-4
starting i/o task 11 Current Thread: VirtualThread[#33,Thread11]/runnable@ForkJoinPool-1-worker-3
starting i/o task 12 Current Thread: VirtualThread[#34,Thread12]/runnable@ForkJoinPool-1-worker-4
starting i/o task 14 Current Thread: VirtualThread[#36,Thread14]/runnable@ForkJoinPool-1-worker-4
starting i/o task 15 Current Thread: VirtualThread[#37,Thread15]/runnable@ForkJoinPool-1-worker-4
starting i/o task 17 Current Thread: VirtualThread[#39,Thread17]/runnable@ForkJoinPool-1-worker-4
starting i/o task 19 Current Thread: VirtualThread[#41,Thread19]/runnable@ForkJoinPool-1-worker-2
starting i/o task 18 Current Thread: VirtualThread[#40,Thread18]/runnable@ForkJoinPool-1-worker-1
Observe that in case of the virtual threads same worker-1 is working on different tasks. When the current task is blocked, the worker thread parks the current task and starts working on another thread.
4. Conclusion
In this tutorial, we discussed the example of Java carrier thread and virtual thread and how these two threads execute threads.