Java 获取虚拟线程挂载的平台线程对应的 ForkJoinPool 实例

Java juc About 4,211 words

反射获取

VirtualThread类中的私有静态final变量DEFAULT_SCHEDULER

import java.lang.reflect.Field;
import java.util.concurrent.ForkJoinPool;

public class JavaVirtualThreadDemo {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class<?> virtualThreadClass = Class.forName("java.lang.VirtualThread");
        Field defaultSchedulerField = virtualThreadClass.getDeclaredField("DEFAULT_SCHEDULER");
        defaultSchedulerField.setAccessible(true);
        Object object = defaultSchedulerField.get(null);
        System.out.println(object);
        ForkJoinPool fjp = (ForkJoinPool) object;
        System.out.println(fjp.getParallelism());
        System.out.println(fjp.getPoolSize());
        System.out.println(fjp.getActiveThreadCount());
        System.out.println(fjp.getRunningThreadCount());
        System.out.println(fjp.getStealCount());
        System.out.println(fjp.getQueuedTaskCount());
        System.out.println(fjp.getQueuedSubmissionCount());
        fjp.setParallelism(100);
        System.out.println(object);
    }

}

输出

java.util.concurrent.ForkJoinPool@38af3868[Running, parallelism = 4, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
4
0
0
0
0
0
0
java.util.concurrent.ForkJoinPool@38af3868[Running, parallelism = 100, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]

源码

package java.lang;

final class VirtualThread extends BaseVirtualThread {

    private static final ForkJoinPool DEFAULT_SCHEDULER = createDefaultScheduler();
    
    /**
     * Creates the default scheduler.
     */
    @SuppressWarnings("removal")
    private static ForkJoinPool createDefaultScheduler() {
        ForkJoinWorkerThreadFactory factory = pool -> {
            PrivilegedAction<ForkJoinWorkerThread> pa = () -> new CarrierThread(pool);
            return AccessController.doPrivileged(pa);
        };
        PrivilegedAction<ForkJoinPool> pa = () -> {
            int parallelism, maxPoolSize, minRunnable;
            String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism");
            String maxPoolSizeValue = System.getProperty("jdk.virtualThreadScheduler.maxPoolSize");
            String minRunnableValue = System.getProperty("jdk.virtualThreadScheduler.minRunnable");
            if (parallelismValue != null) {
                parallelism = Integer.parseInt(parallelismValue);
            } else {
                parallelism = Runtime.getRuntime().availableProcessors();
            }
            if (maxPoolSizeValue != null) {
                maxPoolSize = Integer.parseInt(maxPoolSizeValue);
                parallelism = Integer.min(parallelism, maxPoolSize);
            } else {
                maxPoolSize = Integer.max(parallelism, 256);
            }
            if (minRunnableValue != null) {
                minRunnable = Integer.parseInt(minRunnableValue);
            } else {
                minRunnable = Integer.max(parallelism / 2, 1);
            }
            Thread.UncaughtExceptionHandler handler = (t, e) -> { };
            boolean asyncMode = true; // FIFO
            return new ForkJoinPool(parallelism, factory, handler, asyncMode,
                         0, maxPoolSize, minRunnable, pool -> true, 30, SECONDS);
        };
        return AccessController.doPrivileged(pa);
    }

}

注意

需要添加启动参数,否则反射调用时会报错。

--add-opens java.base/java.lang=ALL-UNNAMED

不加启动会得到以下错误

Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make field private static final java.util.concurrent.ForkJoinPool java.lang.VirtualThread.DEFAULT_SCHEDULER accessible: module java.base does not "opens java.lang" to unnamed module @65b54208
    at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:353)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:329)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:277)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:179)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:173)
Views: 9 · Posted: 2025-12-25

———         Thanks for Reading         ———

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓
Today In History
Browsing Refresh