如何为并行Web服务请求配置ThreadPool?

时间:2017-07-11 14:06:02

标签: java spring multithreading web-services parallel-processing

我想将webservice调用并行发送到webservice。应该有最多20个并行请求等待Web服务响应。任何其他请求都应该等待它们完成。

如果单个用户向我发送请求,这通常会导致向目标服务器发送5个并行请求。 所以我可以立即为最多20/5 = 4个用户提供服务。其他人则必须等待,这很好。或者在真正高负荷下被拒绝。

问题:我应该使用哪个线程池,以及如何配置它?

private ExecutorService asyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(20);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(100);
    executor.initialize();

    //return executor.getThreadPoolExecutor(); //I could as well use this. Which is better??
    return Executors.newFixedThreadPool(20, executor);
}

我读了以上内容:主池可以向网络服务器发送20个并行请求(从而在parralel中立即为4个用户提供服务)。如果所有20个线程都忙,并且第5个用户进入,则请求排队。

问题:

  • 配置正确吗?

  • 为什么我必须另外在nthreads=20设置Executors.newFixedThreadPool()?设置poolSize

  • 有什么区别
  • 是否存在设置corePoolSize=20的性能开销?我的意思是,然后游泳池将永远不会打瞌睡。但我可能无法将其设置得更低(例如为5),因为只有在队列耗尽时才会创建新线程。右

2 个答案:

答案 0 :(得分:1)

我认为

executor.setMaxPoolSize(20) 

可用于通过构造函数覆盖最初设置的线程数,在这种情况下似乎是多余的。同样适用于setCorePoolSize。它只是用于动态控制。 根据池的大小,通常您可以考虑Little's Law

答案 1 :(得分:0)

调用Executors.newFixedThreadPool(20, executor);时,您将先前设置的执行程序作为 ThreadFactory 传递,因为ThreadPoolTask​​Executor实现了ThreadFactory接口。

结果是一个ExecutorService,它以20个线程就绪,最大线程数20和一个无限制的LinkedBlockingQueue开始,等待处理的任务(你可以在这里看到它https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int,%20java.util.concurrent.ThreadFactory))。

关于你的第一个和第二个问题 - 你可以省略Executors.newFixedThreadPool()调用,如果你想使用jdk类ThreadPoolExecutor,只需返回ThreadPoolTask​​Executor或调用它的getThreadPoolExecutor()。

关于你的第三个问题 - 在启动时会有一个惩罚因为jvm必须创建并运行20个线程,但我猜这可以忽略不计。将corePoolSize设置为低于maximumPoolSize的一件事是,未使用的线程将被jvm杀死,这可以减少应用程序的内存占用。

关于在ExecutorService中创建新线程的时间 - 当队列中有任务并且未达到maximumPoolSize时,会创建ExecutorService中的线程。如果达到执行程序中的maximumPoolSize并且队列已满 - 执行程序将为提交给它的每个新任务抛出RejectedExecutionException,直到有新的空间。您可以通过实现自己的RejectedExecutionHandler来更改此行为。