JDK19虚拟线程初探(三)

上两篇文章中,我们已经介绍了使用虚拟线程的例程和VirtualThread。接下来,我们继续介绍虚拟线程的调度,即VirtualThread中最重要的两个成员变量Executor scheduler和Continuation cont。

scheduler是用于虚拟线程调度的线程池,先看虚拟线程的初始化代码:

    VirtualThread(Executor scheduler, String name, int characteristics, Runnable task) {
        super(name, characteristics,  false);
        Objects.requireNonNull(task);

        if (scheduler == null) {
            Thread parent = Thread.currentThread();
            if (parent instanceof VirtualThread vparent) {

                scheduler = vparent.scheduler;
            } else {

                scheduler = DEFAULT_SCHEDULER;
            }
        }

        this.scheduler = scheduler;

        this.cont = new VThreadContinuation(this, task);
        this.runContinuation = this::runContinuation;
    }

默认调度器DEFAULT_SCHEDULER其实就是个ForkJoinPool,创建参数如下:

  • parallelism,可同时执行的线程个数,取值jdk.virtualThreadScheduler.parallelism,默认为Runtime.getRuntime().availableProcessors()。
  • asyncMode,异步工作模式,设置为true,表示FIFO。
  • corePoolSize,池中保持的线程数,设置为0
  • maximumPoolSize,池中最多保持的线程数,取值jdk.virtualThreadScheduler.maxPoolSize
  • minRunnable,正在运行的最小线程数,取值jdk.virtualThreadScheduler.minRunnable
  • keepAliveTime,空闲线程保活时间30秒

提交任务

虚拟线程start()和unpark()时,会调用submitRunContinuation()方法提交任务,代码如下:

        try {

            if (lazySubmit && scheduler instanceof ForkJoinPool pool) {
                pool.lazySubmit(ForkJoinTask.adapt(runContinuation));
            } else {

                scheduler.execute(runContinuation);
            }
        }
  • ForkJoinPool的lazySubmit是JDK19的新增方法,机制类似于Jetty的EatWhatYouKill,尽量让调用线程执行提交的任务。

先看看continuation的成员变量:


private static final VarHandle MOUNTED;

private volatile boolean mounted = false;

private final Runnable target;

private final ContinuationScope scope;

private Continuation parent;

private Continuation child;

初始化


    public Continuation(ContinuationScope scope, Runnable target) {
        this.scope = scope;
        this.target = target;
    }

run()

虚拟线程runContinuation会调用到Continuation的run方法,实际执行任务,代码如下:

    public final void run() {
        while (true) {

            mount();
            JLA.setExtentLocalCache(extentLocalCache);

            if (done)
                throw new IllegalStateException("Continuation terminated");

            Thread t = currentCarrierThread();

            if (parent != null) {
                if (parent != JLA.getContinuation(t))
                    throw new IllegalStateException();
            } else
                this.parent = JLA.getContinuation(t);
            JLA.setContinuation(t, this);

            try {

                boolean isVirtualThread = (scope == JLA.virtualThreadContinuationScope());
                if (!isStarted()) {

                    enterSpecial(this, false, isVirtualThread);
                } else {
                    assert !isEmpty();

                    enterSpecial(this, true, isVirtualThread);
                }
            } finally {

                fence();
                try {
                    assert isEmpty() == done : "empty: " + isEmpty() + " done: " + done + " cont: " + Integer.toHexString(System.identityHashCode(this));

                    JLA.setContinuation(currentCarrierThread(), this.parent);
                    if (parent != null)
                        parent.child = null;

                    postYieldCleanup();

                    unmount();
                    if (PRESERVE_EXTENT_LOCAL_CACHE) {
                        extentLocalCache = JLA.extentLocalCache();
                    } else {
                        extentLocalCache = null;
                    }
                    JLA.setExtentLocalCache(null);
                } catch (Throwable e) { e.printStackTrace(); System.exit(1); }
            }

        }
    }

run()方法和yield()方法配合,yield()可以中断Continuation执行,run()可以执行或者继续执行实际任务。

总共花三篇文章大概介绍了JDK19中新增的虚拟线程,从LOOM Project的纤程、阿里的wisp和wisp2、到今天JEP 425中的虚拟线程,官方提供的生产可用的用户态线程方案距离我们越来越近了。

Original: https://blog.csdn.net/a860MHz/article/details/127818347
Author: 860MHz
Title: JDK19虚拟线程初探(三)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/659232/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球