java - 在服务中配置线程池大小

标签 java multithreading concurrency threadpool executorservice

我正在编写一个服务,它需要两个 URL urlAurlB 来获取两个整数 ab。该服务返回 absum

该服务最简单的形式是这样工作的:

public Integer getSumFromUrls(String urlA, String urlB) {

    Integer a = fetchFromUrl(urlA);
    Integer b = fetchFromUrl(urlB);

    return a + b;
}

这里fetchFromUrl是一个同步操作,因此除非该值可用,否则它会阻塞处理线程。为了提高效率,我宁愿使用 ExecutorService 来安排两次获取并在结果可用时返回。这是更改后的代码(忽略语法细微差别)

public Integer getSumFromUrls(String urlA, String urlB) {
    Future<Integer> aFuture = Executors.newSingleThreadScheduledExecutor().submit(new Callable<Integer>() {
        public Integer call() {
            return fetchFromUrl(urlA);
        }

    });
    Future<Integer> bFuture = Executors.newSingleThreadScheduledExecutor().submit(new Callable<Integer>() {
        public Integer call() {
            return fetchFromUrl(urlB);
        }                                                                                
    });

    Integer a = aFuture.get();
    Integer b = bFuture.get();

    return a + b;
}

在这里,我创建了单线程执行器来并发执行请求。

由于此代码将在 Web 服务的上下文中运行,因此我可能不应该在函数内部本地创建单线程执行器,而应该使用跨请求共享的一些 N 大小的线程池。

我的问题是:

  1. 上述理解(斜体部分)正确吗?
  2. 如果是,我应该如何选择线程池的最佳大小。它应该是我的服务容器的线程池大小或请求吞吐量或两者等的函数吗?
  3. 是否有更好的方法来优化此场景,以便服务线程在大多数时间执行 IO 时不会被阻塞。

注意:此问题中提供的详细信息并非完全真实的场景,但代表了回答该问题所需的同一组复杂性。

最佳答案

如果你的函数getSumFromUrls在每次新请求到来时执行,这意味着它每次都会创建一个新的ThreadPool并提交任务。假设如果您在任何时间点都有 1000 请求命中,则将创建 1000 ThreadPool,并最终创建 1000s 线程。我相信,如果您在任何时间创建 1000 个或更多线程,这对您的应用程序来说都是一个问题。一般来说,在任何时间点, Activity 线程的数量都应该大约/等于系统的可用核心数量,但这完全取决于用例,假设您的任务是CPU密集型,那么线程数量应该与CPU核心大小相同,但如果您的任务是IO密集型,那么您可以拥有更多数量的线程。更多数量的线程意味着将发生更多数量的上下文切换,这有其自身的成本,并且可能会降低应用程序性能。

以上理解(斜体部分)正确吗?

-> Yes.

如果是,我应该如何选择线程池的最佳大小。它应该是我的服务容器的线程池大小的函数,还是请求吞吐量或两者的函数?

-> As I have mentioned above it depends on the which type of task you are doing. You should use common thread pool to execute those task.

是否有更好的方法来优化此场景,以便服务线程在大多数时间执行 IO 时不会被阻塞?

-> You should benchmark thread pool size and operating system automatically assign the CPU to another thread when a thread doing IO operation and do not need the CPU.

关于java - 在服务中配置线程池大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58048718/

相关文章:

C++ Windows 窗口是否强制唤醒等待中的线程?

Java:您可以在不显式创建 block 的情况下同步变量吗?

java - 写但不读时java中的同步 HashMap

java - 二维数组 : Retrieving Row/Column and not value

java - JPanel的目的?

java - 如何在拖放过程中接收关键事件?

java - 字符串数组 - 不必要的同步?

C# 在其他线程上执行方法

PHP MySQL并发,数据库中的最大项目数有限

Java i/o 程序错误 throwFor(未知来源)