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扫描下方二维码关注公众号和小程序↓↓↓
Loading...