FixedThreadPool 最多创建多少个线程?

What are the maximum number of threads created in FixedThreadPool?

最近导师让我实现自己的FixedThreadPool。该池一次最多只能有 N 个固定数量的线程执行。 Pool 也有机制,如果它已满,Runnables 将不得不等待其他人完成。在 java 中,我们可以使用 -

来实现
ThreadPoolExecutor tpe = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
tpe.execute(t1);
tpe.execute(t2);
tpe.execute(t3);
tpe.execute(t4);

在我的实现中,我总是创建一个 new Thread 对象并在启动它之前将提供的 Runnables 传递给它。所以我创建的线程总数(使用 new 关键字)总是等于 Runnable 的数量。但是,处于 运行 状态的最大线程数将按照用户设置的 N 进行设置。

这个实现被我的导师拒绝了,他向我解释说线程池的目标是重用线程,所以你应该只创建 N 个线程并将它们用于多个 Runnable。

但是当我深入 ThreadPoolExecutor.execute 原生 Java 代码的实现时,我发现它使用某种工厂为每个 Runnable 创建了一个新对象。

来自 java 代码的屏幕截图

现在这在某种程度上与 ThreadPool 的定义相矛盾,ThreadPool 表示线程被重用。请澄清这一点,因为我很难理解这个概念(这是以正确的方式实现我自己的池所必需的)。

P.S。请原谅我糟糕的语法

所以,从我的角度来看,线程池工作算法是如何相似的,如下所示

while (check if the pool is not shutdown) {
    Runnable task = pool.fetchTaskFromQueue(); // fetch the Task from the queue. In your case it object of MyRunnable class
    task.run(); // call the run() of MyRunnable object
}

线程池resues Thread,而不是Runnable/ Callable(Thread class 也是Runnable 的一个实现)实现。因此,如果您在 ExecutorService#execute 中传递 Thread 的对象,它永远不会在您作为 executeargument 发送的线程对象上调用 Thread#start , 它只会从 ThreadPool's 自己的线程调用 Thread#run

What is the maximum number of threads created in FixedThreadPool?

-> 根据您的代码,ThreadPool 中线程 Thread 的最大数量为 3。

这是来自 java.util.concurrent.ThreadPoolExecutor

execute 函数的文档
     /*
     * Proceed in 3 steps:
     *
     * 1. If fewer than corePoolSize threads are running, try to
     * start a new thread with the given command as its first
     * task.  The call to addWorker atomically checks runState and
     * workerCount, and so prevents false alarms that would add
     * threads when it shouldn't, by returning false.
     *
     * 2. If a task can be successfully queued, then we still need
     * to double-check whether we should have added a thread
     * (because existing ones died since last checking) or that
     * the pool shut down since entry into this method. So we
     * recheck state and if necessary roll back the enqueuing if
     * stopped, or start a new thread if there are none.
     *
     * 3. If we cannot queue task, then we try to add a new
     * thread.  If it fails, we know we are shut down or saturated
     * and so reject the task.
     */

所以基本上,如果线程少于 corePoolSize 运行 或如果旧线程死亡,将创建新线程。否则,他们将排队(使用 LinkedBlockingQueue