我想使用一个通用线程池,该线程池可以在我的应用程序中随处使用。我应该在主类中创建一个静态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()设置为静态。我做得对吗?
答案 0 :(得分:1)
您应该担心,每次调用getDetails时,此代码都会创建一个新的线程池。最终,如果对其进行足够的调用,您将耗尽线程。
您可以将ExecutorService保存在静态变量中,然后检索保存的引用,而不是每次都创建一个新引用。或者,您可以使用依赖项注入,并让DI框架将其注入到需要的地方。
答案 1 :(得分:1)
创建线程是expensive,而池可以重用现有线程,从而提高了性能。
为每个请求创建线程池都违反了design:
线程池解决了两个不同的问题:
它们通常在执行大量数字时提供改进的性能 异步任务,因为减少了每个任务的调用开销,
并且它们提供了一种方法来限制和管理资源, 包括线程,在执行一组任务时消耗。
因此最好创建一个singlton线程池并在各处使用它。
如果您决定为每个请求创建一个线程池,请确保在所有任务完成后shutdown将其创建,否则将不会对该线程池进行垃圾收集,最终导致OutOfMemory。 / p>