首页 > 解决方案 > 具有最小和最大线程数的 ScheduledExecutorService

问题描述

我正在尝试使用 ScheduledExecutorService 在给定的线程池上安排任务。

public ScheduledExecutorService scheduledExecutorService() {
    return Executors.newScheduledThreadPool(3);
}

看起来这种创建实例的方式假定用户指定的值作为最小线程数,最大线程数将是Integer.MAX_VALUE(默认值)。

如何为 ScheduledExecutorService 的实例指定最大线程数?我无法将如此庞大的线程数分配为最大线程数。

反编译后的 jar 序列中的代码片段 -

// From Executors.java
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

// From ScheduledThreadPoolExecutor.java
public ScheduledThreadPoolExecutor(int corePoolSize) {
    super(corePoolSize, Integer.MAX_VALUE,
          DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
          new DelayedWorkQueue());
}

// From ThreadPoolExecutor.java
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

如果我在 Java 文档中缺少引用方法,请指出正确的位置。TIA。

标签: javamultithreading

解决方案


ConstructorofScheduledThreadPoolExecutor不直接提供该参数的设置。您可以手动调用setMaximumPoolSize方法:

    public ScheduledExecutorService scheduledExecutorService() {
        ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize);
        scheduledThreadPoolExecutor.setMaximumPoolSize(xxx);
        return scheduledThreadPoolExecutor;
    }

但是在 中设置 thismaximumPoolSize是没有意义的ScheduledThreadPoolExecutor ,这也是构造函数没有声明这个参数的原因。

来自 Java 文档ScheduledThreadPoolExecutor

虽然这个类继承自 ThreadPoolExecutor,但一些继承的调优方法对它没有用。特别是,因为它充当使用 corePoolSize 线程和无界队列的固定大小的池,所以对 maximumPoolSize 的调整没有有用的效果。此外,将 corePoolSize 设置为零或使用 allowCoreThreadTimeOut 几乎不是一个好主意,因为一旦它们有资格运行,这可能会使池没有线程来处理任务。

更多细节,见和 ,delayedExecuteensurePrestart无用的。ScheduledThreadPoolExecutormaximumPoolSize

   private void delayedExecute(RunnableScheduledFuture<?> task) {
        if (isShutdown())
            reject(task);
        else {
            // add task to queue
            super.getQueue().add(task);
            if (isShutdown() &&
                !canRunInCurrentRunState(task.isPeriodic()) &&
                remove(task))
                task.cancel(false);
            else
                ensurePrestart();
        }
    }

    void ensurePrestart() {
        int wc = workerCountOf(ctl.get());
        if (wc < corePoolSize)
            addWorker(null, true);
        else if (wc == 0)
            addWorker(null, false);
    }

推荐阅读