import java.util.Arrays; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class ThreadOverhead { private static final int ASIZE = 1000; private static class Dummy implements Runnable { @Override public void run() { Random rng = new Random(); int[] a = new int[ASIZE]; for(int i = 0; i < ASIZE; i++) a[i] = rng.nextInt(); Arrays.sort(a); if(a[0] > a[ASIZE - 1]) throw new RuntimeException("Houston we have a problem"); } } private static final int NTASK = 500000; private static int measure(int nthreads) throws InterruptedException { long t1 = System.currentTimeMillis(); ExecutorService es = Executors.newFixedThreadPool(nthreads); for(int i = 0; i < NTASK; i++) { es.submit(new Dummy()); } es.shutdown(); es.awaitTermination(300, TimeUnit.SECONDS); long t2 = System.currentTimeMillis(); return (int)(t2 - t1); } public static void main(String[] args) throws Exception { int[] n = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000 }; int[] t = new int[n.length]; for(int i = 0; i < n.length; i++) t[i] = measure(n[i]); int mint = Arrays.stream(t).min().getAsInt(); System.out.printf("%-7s %-7s %s\n", "Threads", "Time", "Performance"); for(int i = 0; i < n.length; i++) { System.out.printf("%7d %7d %5.1f%%\n", n[i], t[i], 100.0 * mint / t[i]); } } } Standard Java 11: C:\Work\T>java ThreadOverhead Threads Time Performance 1 28131 19.8% 2 14663 37.9% 3 9792 56.8% 4 7771 71.6% 5 6806 81.7% 6 6325 88.0% 7 5840 95.3% 8 5563 100.0% 9 5634 98.7% 10 5584 99.6% 20 5727 97.1% 30 5668 98.1% 40 5706 97.5% 50 5942 93.6% 60 5761 96.6% 70 5707 97.5% 80 5687 97.8% 90 5849 95.1% 100 5809 95.8% 200 5877 94.7% 300 5869 94.8% 400 6338 87.8% 500 6379 87.2% 600 6361 87.5% 700 6356 87.5% 800 6463 86.1% 900 6532 85.2% 1000 6449 86.3% 2000 6633 83.9% 3000 7287 76.3% 4000 7427 74.9% 5000 7737 71.9% 6000 8279 67.2% 7000 8479 65.6% 8000 8882 62.6% 9000 9253 60.1% 10000 9623 57.8% Java 16 Loom build: C:\Work\T>java ThreadOverhead Threads Time Performance 1 26777 19.2% 2 13388 38.5% 3 9311 55.3% 4 7205 71.5% 5 6308 81.7% 6 5896 87.4% 7 5485 93.9% 8 5284 97.5% 9 5251 98.1% 10 5152 100.0% 20 5185 99.4% 30 5335 96.6% 40 5391 95.6% 50 5332 96.6% 60 5281 97.6% 70 5327 96.7% 80 5301 97.2% 90 17213 29.9% 100 5259 98.0% 200 5355 96.2% 300 5570 92.5% 400 5543 92.9% 500 5543 92.9% 600 5508 93.5% 700 5561 92.6% 800 5758 89.5% 900 5685 90.6% 1000 5743 89.7% 2000 5862 87.9% 3000 6008 85.8% 4000 6327 81.4% 5000 6373 80.8% 6000 6647 77.5% 7000 6779 76.0% 8000 6986 73.7% 9000 7728 66.7% 10000 7366 69.9% import java.util.Arrays; import java.util.Random; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class VirtualThreadOverhead { private static final int ASIZE = 1000; private static class Dummy implements Runnable { @Override public void run() { Random rng = new Random(); int[] a = new int[ASIZE]; for(int i = 0; i < ASIZE; i++) a[i] = rng.nextInt(); Arrays.sort(a); if(a[0] > a[ASIZE - 1]) throw new RuntimeException("Houston we have a problem"); } } private static final int NTASK = 500000; private static int measure(int nthreads) throws InterruptedException { long t1 = System.currentTimeMillis(); ExecutorService es = Executors.newFixedThreadPool(nthreads, Thread.builder().virtual().factory()); for(int i = 0; i < NTASK; i++) { es.submit(new Dummy()); } es.shutdown(); es.awaitTermination(300, TimeUnit.SECONDS); long t2 = System.currentTimeMillis(); return (int)(t2 - t1); } public static void main(String[] args) throws Exception { int[] n = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000 }; int[] t = new int[n.length]; for(int i = 0; i < n.length; i++) t[i] = measure(n[i]); int mint = Arrays.stream(t).min().getAsInt(); System.out.printf("%-7s %-7s %s\n", "Threads", "Time", "Performance"); for(int i = 0; i < n.length; i++) { System.out.printf("%7d %7d %5.1f%%\n", n[i], t[i], 100.0 * mint / t[i]); } } } C:\Work\T>java VirtualThreadOverhead Threads Time Performance 1 26878 20.5% 2 13917 39.6% 3 10068 54.8% 4 8081 68.3% 5 6816 80.9% 6 6210 88.8% 7 6114 90.2% 8 5843 94.4% 9 5799 95.1% 10 5863 94.1% 20 5943 92.8% 30 5739 96.1% 40 5765 95.7% 50 5583 98.8% 60 5516 100.0% 70 6121 90.1% 80 5622 98.1% 90 6271 88.0% 100 6296 87.6% 200 6241 88.4% 300 6237 88.4% 400 5917 93.2% 500 6198 89.0% 600 6329 87.2% 700 6151 89.7% 800 6490 85.0% 900 6067 90.9% 1000 5732 96.2% 2000 6247 88.3% 3000 6081 90.7% 4000 6315 87.3% 5000 6123 90.1% 6000 6356 86.8% 7000 6424 85.9% 8000 6471 85.2% 9000 6028 91.5% 10000 6219 88.7%