为什么ForkJoinPool可以创建出类型为ForkJoinWorkerThread的线程?

直接看下ForkJoinPool的无参构造方法,如下:

ForkJoinPool forkJoinPool = new ForkJoinPool();

跟进构造方法源码中,如下:

public static final ForkJoinWorkerThreadFactory
    defaultForkJoinWorkerThreadFactory;


public ForkJoinPool() {
    this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
         defaultForkJoinWorkerThreadFactory, null, false);
}

public ForkJoinPool(int parallelism,
                    ForkJoinWorkerThreadFactory factory,
                    UncaughtExceptionHandler handler,
                    boolean asyncMode) {
    this(checkParallelism(parallelism),
         checkFactory(factory),
         handler,
         asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
         "ForkJoinPool-" + nextPoolId() + "-worker-");
    checkPermission();
}

private ForkJoinPool(int parallelism,
                     ForkJoinWorkerThreadFactory factory,
                     UncaughtExceptionHandler handler,
                     int mode,
                     String workerNamePrefix) {
    this.workerNamePrefix = workerNamePrefix;
    this.factory = factory;
    this.ueh = handler;
    this.config = (parallelism & SMASK) | mode;
    long np = (long)(-parallelism); // offset ctl counts
    this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
}

可以发现以上方法中有个默认的参数ForkJoinWorkerThreadFactory,故名思义,这就是ForkJoinWorkerThread的工厂类,默认构造函数中对应这个参数的是defaultForkJoinWorkerThreadFactory,该属性是ForkJoinWorkerThreadFactory接口类实例,那么接着看看ForkJoinWorkerThreadFactory接口类对应的实现类,如下:

static final class DefaultForkJoinWorkerThreadFactory
    implements ForkJoinWorkerThreadFactory {
    public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
        return new ForkJoinWorkerThread(pool);
    }
}

这时候可以发现该DefaultForkJoinWorkerThreadFactory类的方法newThread()返回的参数结果就是ForkJoinWorkerThread类型,到这里可以了解到,ForkJoinWorkerThread类的发源地在哪个方法,然后参考下其他线程池的思想,猜测ForkJoinPool线程池也是在提交任务时,创建相应的ForkJoinWorkerThread线程去执行任务,所以跟进ForkJoinPool的提交任务的方法,如下:

public <T> T invoke(ForkJoinTask<T> task) {
    if (task == null)
        throw new NullPointerException();
    externalPush(task);
    return task.join();
}

继续跟进externalPush()方法,会发现有一个signalWork()方法被调用来激活任务,如下:
在这里插入图片描述
跟进signalWork()方法,如下:
在这里插入图片描述
可以发现里面有个tryAddWorker()方法,跟进tryAddWorker()方法,如下:

在这里插入图片描述
发现里面有个createWorker()方法,继续跟进createWorker()方法,如下:
在这里插入图片描述
最后发现DefaultForkJoinWorkerThreadFactory类的方法newThread()被调用了用来生成工作线程。

总结

和其他线程池类似,ForkJoinPool线程池也是在提交任务时决定是否要新建线程去执行任务,如果需要新建线程,就会调用ForkJoinWorkerThreadFactory接口的newThread()方法,返回ForkJoinWorkerThread类型的线程。

猜你喜欢

转载自blog.csdn.net/weixin_38106322/article/details/107609220