ExecutorService(int n) 和 Thread.activeCount() 是如何工作的?

How does the ExecutorService(int n) and Thread.activeCount() work?

我有以下代码片段:

int k = 4;

        ExecutorService e = Executors.newFixedThreadPool(k);
        for (int i = 1; i <= k; i++) {
            e.execute(new C(i));
            e.execute(new C(i));
        }
        int active = Thread.activeCount();
        System.out.println(active);
        e.shutdown();

清晰可见我通过循环每次迭代提交两个 C。在我的例子中,提交了 8 C,即使 ExecutorService 的大小固定为 4。 这也可以通过计算活动线程 5 来确认。

这种行为是故意的吗?我不明白为什么似乎只有 4 个新线程被启动和计数,尽管提交了 8 个。如果有人能为我澄清 ExecutorService 和 Thread.activeCount() 的概念,我会很高兴。

您创建的 ExecutorService 的主要目标是一个 fixed-size 线程池(在您的例子中是四个线程)。如果您只看到为您的八项工作创建了四个 Thread 实例,那么它正在按设计工作。

您似乎认为应该创建八个线程。想象一下,如果您提交了 100 万件作品;如果创建一百万个线程,那将是一场灾难。

抽象允许您控制一次使用多少线程,而不考虑有多少项目要处理。 ExecutorService 处理根据需要多次重用四个线程的复杂性,以处理您传递给调用 execute.

的所有项目

可以用银行来类比。您创建了一家银行,其中有四个出纳员(线程池中的四个线程)和八个客户(对 execute 的八次调用)。当出纳员完成与客户的交易后,排队的下一位客户将由该出纳员提供服务。您通过调用 execute 将某人添加到队列中,ExecutorService 管理其他一切。您可以通过初始化 ExecutorService 的方式来控制线程(出纳员)的数量(您可以创建许多不同的风格)。

I don't understand why seemingly just 4 new threads are started and counted, eventhough 8 are submitted.

不要混淆线程和任务。您已经为 4 个线程创建了一个固定的 ThreadPool,池中将只保留 4 个线程。

检查 Executors

的实现
 /**
     * Creates a thread pool that reuses a fixed number of threads
     * operating off a shared unbounded queue.  At any point, at most
     * <tt>nThreads</tt> threads will be active processing tasks.
     * If additional tasks are submitted when all threads are active,
     * they will wait in the queue until a thread is available.
     * If any thread terminates due to a failure during execution
     * prior to shutdown, a new one will take its place if needed to
     * execute subsequent tasks.  The threads in the pool will exist
     * until it is explicitly {@link ExecutorService#shutdown shutdown}.
     *
     * @param nThreads the number of threads in the pool
     * @return the newly created thread pool
     * @throws IllegalArgumentException if <tt>nThreads &lt;= 0</tt>
     */
    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

您可以在官方文档页面找到有关 ThreadPoolExecutor 各个参数的更多详细信息。

在你的例子中,线程数是 4。工作任务(实现 Runnable 接口)的数量是 8。

How are they stored, how can they be accessed? Is it also possible to manipulate them midway, maybe why other calls arrive?

  1. 任务已提交到任务队列(BlockingQueue
  2. 如果BlockingQueue已满(有界队列),将触发拒绝策略。
  3. 如果 BlockingQueue 未满,工作任务将等待 Thread pick-up 它们。

相关 SE 帖子: