全局执行器服务
Global Executor Service
我想使用一个公共线程池,它可以在我的应用程序中随处使用。我要在主 class 中创建一个静态执行器服务吗?然后在需要的地方使用它?目前我的主要 class(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);
}
我的线程池class:
@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;
}
}
在我的实现中 class(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)。或者所有请求都将使用带有 common/same 线程池的公共执行程序服务,该线程池为 (25 corePoolSize, 50 maxPoolSize, 1000 keepTimeAlive)。为了实现这一点,我将 main 中的 getExecutor() 设为静态。我做得对吗?
你的担心是对的,这段代码会在你每次调用 getDetails 时创建一个新的线程池。最终,如果对其进行足够多的调用,您将 运行 超出线程。
您可以将 ExecutorService 保存在静态变量中并检索保存的引用,而不是每次都创建一个新引用。或者,您可以使用依赖注入,让 DI 框架将其注入到需要的地方。
创建线程是expensive,而池可以重新使用现有线程,从而提高性能。
为每个请求创建一个线程池违反了它design:
Thread pools address two different problems:
they usually provide improved performance when executing large numbers
of asynchronous tasks, due to reduced per-task invocation overhead,
and they provide a means of bounding and managing the resources,
including threads, consumed when executing a collection of tasks.
所以还是弄个单例线程池到处用吧
如果您决定为每个请求创建一个线程池,请确保最终 shutdown it after all tasks finish, otherwise the pool will not be garbage collected, which leads to 。
我想使用一个公共线程池,它可以在我的应用程序中随处使用。我要在主 class 中创建一个静态执行器服务吗?然后在需要的地方使用它?目前我的主要 class(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);
}
我的线程池class:
@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;
}
}
在我的实现中 class(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)。或者所有请求都将使用带有 common/same 线程池的公共执行程序服务,该线程池为 (25 corePoolSize, 50 maxPoolSize, 1000 keepTimeAlive)。为了实现这一点,我将 main 中的 getExecutor() 设为静态。我做得对吗?
你的担心是对的,这段代码会在你每次调用 getDetails 时创建一个新的线程池。最终,如果对其进行足够多的调用,您将 运行 超出线程。
您可以将 ExecutorService 保存在静态变量中并检索保存的引用,而不是每次都创建一个新引用。或者,您可以使用依赖注入,让 DI 框架将其注入到需要的地方。
创建线程是expensive,而池可以重新使用现有线程,从而提高性能。
为每个请求创建一个线程池违反了它design:
Thread pools address two different problems:
they usually provide improved performance when executing large numbers of asynchronous tasks, due to reduced per-task invocation overhead,
and they provide a means of bounding and managing the resources, including threads, consumed when executing a collection of tasks.
所以还是弄个单例线程池到处用吧
如果您决定为每个请求创建一个线程池,请确保最终 shutdown it after all tasks finish, otherwise the pool will not be garbage collected, which leads to