全球执行员服务

时间:2018-10-31 02:25:29

标签: java multithreading static executorservice threadpoolexecutor

我想使用一个通用线程池,该线程池可以在我的应用程序中随处使用。我应该在主类中创建一个静态Executor服务。然后在需要的地方使用它?目前,我的主类(MyMainApplication.java)中有这个

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

public static final ThreadPoolExecutor getExecutor(int corePoolSize, int maxPoolSize, int keepAlive) {
    return ThreadPools.getExecutor(corePoolSize, maxPoolSize, keepAlive);
}

我的线程池类:

@Component
public class ThreadPools {

private static final int DEFAULT_CORE_POOL_SIZE = 5;
private static final int DEFAULT_MAX_POOL_SIZE = 10;
private static final int DEFAULT_KEEP_ALIVE_MS = 240;
private static int corePoolSize = DEFAULT_CORE_POOL_SIZE;
private static int maxPoolSize = DEFAULT_MAX_POOL_SIZE;
private static int poolKeepAliveInMillis = DEFAULT_KEEP_ALIVE_MS;

public static ThreadPoolExecutor getExecutor(int cpSize, int maxSize, int msTime) {

    if (cpSize != 0) {
        setCorePoolSize(cpSize);
    }
    if (maxSize != 0) {
        setMaxPoolSize(maxSize);
    }
    if (msTime != 0) {
        setKeepAlive(msTime);
    }

    return new ThreadPoolExecutor(corePoolSize, maxPoolSize, poolKeepAliveInMillis, TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<Runnable>(corePoolSize));
}

public static void setCorePoolSize(int size) {
    ThreadPools.corePoolSize = size;
}

public static void setMaxPoolSize(int size) {
    ThreadPools.maxPoolSize = size;
}

public static void setKeepAlive(int time) {
    ThreadPools.poolKeepAliveInMillis = time;
}

}

在我的实现类(GetDetails.java)中,我通过以下方式获取执行程序。

    public void getDetails()
    {
    int corePoolSize=25;
    int maxPoolSize=50;
    int KeepAliveTimeMs=1000;
    ExecutorService executor = MyMainApplication.getExecutor(corePoolSize, 
    maxPoolSize, keepAlive);
    ..........
    ..........
    executor.execute(runnableTask);
   }

我关心的是每次调用getDetails()时,它将使用一组新的池创建一个新的执行程序服务。例如在生产环境中如果大约有100个对getDetails()的请求,它将导致创建100个执行器服务,每个执行器都有自己的线程池集合,即100 *(25 corePoolSize,50 maxPoolSize,1000 keepTimeAlive)。或所有请求将使用具有相同/相同线程池的公共执行程序服务(25 corePoolSize,50 maxPoolSize,1000 keepTimeAlive)。为此,我已将main中的getExecutor()设置为静态。我做得对吗?

2 个答案:

答案 0 :(得分:1)

您应该担心,每次调用getDetails时,此代码都会创建一个新的线程池。最终,如果对其进行足够的调用,您将耗尽线程。

您可以将ExecutorService保存在静态变量中,然后检索保存的引用,而不是每次都创建一个新引用。或者,您可以使用依赖项注入,并让DI框架将其注入到需要的地方。

答案 1 :(得分:1)

创建线程是expensive,而池可以重用现有线程,从而提高了性能。

为每个请求创建线程池都违反了design

  

线程池解决了两个不同的问题:

     

它们通常在执行大量数字时提供改进的性能   异步任务,因为减少了每个任务的调用开销,

     

并且它们提供了一种方法来限制和管理资源,   包括线程,在执行一组任务时消耗。

因此最好创建一个singlton线程池并在各处使用它。


如果您决定为每个请求创建一个线程池,请确保在所有任务完成后shutdown将其创建,否则将不会对该线程池进行垃圾收集,最终导致OutOfMemory。 / p>