在FixedThreadPool中创建的最大线程数是多少?

时间:2018-05-05 17:36:31

标签: java multithreading threadpool

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

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

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

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

但是当我在本机Java代码中执行ThreadPoolExecutor.execute时,我发现它使用某种工厂为每个Runnable创建了一个新对象。

来自java代码的屏幕截图

enter image description here

现在这与ThreadPool的定义有些矛盾,后者说线程被重用了。请澄清这一点,因为我很难理解这个概念(这对于以正确的方式实现我自己的池是必要的)。

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

2 个答案:

答案 0 :(得分:0)

因此,从我的观点来看,线程池工作算法将如何相似,如下所示

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
}

线程池重新生成Thread,而不是Runnable/ Callable(Thread类也是Runnable的实现)实现。因此,如果您在Thread中传递ExecutorService#execute的对象,则永远不会在您作为Thread#start的{​​{1}}发送的线程对象上调用argument ,它只会从execute自己的主题调用Thread#run

  

在FixedThreadPool中创建的最大线程数是多少?

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

答案 1 :(得分:0)

这是来自execute

java.util.concurrent.ThreadPoolExecutor函数的文档
     /*
     * 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