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
的对象,它永远不会在您作为 execute
的 argument
发送的线程对象上调用 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
)
最近导师让我实现自己的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
的对象,它永远不会在您作为 execute
的 argument
发送的线程对象上调用 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
)