Java 全球执行人服务

Java 全球执行人服务,java,multithreading,static,executorservice,threadpoolexecutor,Java,Multithreading,Static,Executorservice,Threadpoolexecutor,我想使用一个公共线程池,可以在我的应用程序中使用,无论我想在哪里。我应该在主类中创建一个静态执行器服务吗。然后在需要的地方使用它?目前我的主类(MyMainApplication.java)中有这个 我的线程池类: @Component public class ThreadPools { private static final int DEFAULT_CORE_POOL_SIZE = 5; private static final int DEFAULT_MAX_POOL_SIZE = 1

我想使用一个公共线程池,可以在我的应用程序中使用,无论我想在哪里。我应该在主类中创建一个静态执行器服务吗。然后在需要的地方使用它?目前我的主类(MyMainApplication.java)中有这个

我的线程池类:

@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()时,它是否会使用一组新的池创建一个新的executor服务。例如,在生产环境中。若对getDetails()有大约100个请求,它会导致创建100个executor服务,每个服务都有自己的线程池集,即100*(25个corePoolSize,50个maxPoolSize,1000个keepTimeAlive)。或者所有请求都将使用一个公共执行器服务和一个公共/相同的线程池(25个corePoolSize、50个maxPoolSize、1000个keepTimeAlive)。为了实现这一点,我将main中的getExecutor()设置为静态。我做得对吗?

你说得对,每次调用getDetails时,这段代码都会创建一个新的线程池。最终,如果对它进行足够多的调用,线程就会用完

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

创建线程是可行的,而池可以重用现有线程,从而提高性能

为每个请求创建线程池违反了以下要求:

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

它们通常在执行大量数据时提供改进的性能 由于减少了每个任务的调用开销

它们提供了一种界定和管理资源的手段, 包括线程,在执行任务集合时使用

所以最好创建一个singlton线程池,并在任何地方使用它



如果您决定为每个请求创建一个线程池,请确保在所有任务完成后创建该线程池,否则该线程池将不会被垃圾收集,最终会导致错误。

感谢您的响应。我修改了代码,在我的主类中创建了一个公共静态ExecutorService变量。我将从getDetails()api检索它。我需要关闭Executor服务吗?如果是,我应该在何时/何地关闭它。因为它是静态的,如果我关闭它,关闭后的请求将被拒绝,对吗?因此,避免调用shutdown()可以吗?@Jack:您应该调用shutdown,否则池的线程将使JVM保持活动状态。提交到池中的任务应该处理中断,以便池可以告诉它们完成。在我的主类中,我创建了一个带有“PreDestroy”注释的方法。我要关闭这里的遗嘱执行人服务。应该没问题吧?谢谢你的回复。我决定在我的主类中创建一个静态executorService变量,而不是为每个请求创建一个新的线程池。我将从实现类(getDetails())API中使用它。如果这个Executor服务是静态的,我还需要关闭它吗?@Jack当你想终止整个应用程序时,你可以关闭它。
@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;
}
    public void getDetails()
    {
    int corePoolSize=25;
    int maxPoolSize=50;
    int KeepAliveTimeMs=1000;
    ExecutorService executor = MyMainApplication.getExecutor(corePoolSize, 
    maxPoolSize, keepAlive);
    ..........
    ..........
    executor.execute(runnableTask);
   }