java中ThreadPoolExecutor maximumPoolSize的功能是什么

时间:2018-12-25 03:20:35

标签: java multithreading threadpool threadpoolexecutor

我正在努力做一些简单的事情……

我的真实项目多年来一直遭受着一个未知问题的困扰,他们决定创建一个非常简单的测试,结果让我感到恐惧...

这是测试:

ExecutorService t = new ThreadPoolExecutor(10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(600));
        for (int i = 0; i < 100; i++) {
            final int i1 = i;
            t.execute(new Runnable() {

                @Override
                public void run() {
                    while (true) {
                        System.out.println(i1);
                        try {
                            Thread.sleep(5000);
                        }
                        catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            });
        }

我正在创建一个包含10个核心线程和20个maximumPoolSize的线程池 然后我给它100个线程,每个线程将简单地打印一个固定的数字...

我的愚蠢愚蠢的想法是

  

该池有10个线程,将在某些时间后随机打印0-9   实例将创建10个额外线程,并且池将以0-19打印   随机

这对我来说很明显,因为maxSize为20,在最坏的情况下它应该接受20个任务...

但是结果是永远打印0-9

问题是:如果maximumPoolSize从未计划执行额外的线程,那又有什么意义呢?

2 个答案:

答案 0 :(得分:3)

正如@Oleg指出的那样,该池工作正常,但是有一个我不知道的实现细节。

仅当任务队列已满时才会创建额外的线程

本文更好地解释了: http://www.bigsoft.co.uk/blog/2009/11/27/rules-of-a-threadpoolexecutor-pool-size

  

以这个例子为例。起始线程池大小为1,核心池大小为   5,最大池大小为10,队列为100。

     

Sun的方式:随着请求进入线程,最多将创建5个线程,然后   任务将被添加到队列中,直到达到100。   是完整的新线程,最多将创建到maxPoolSize。一旦所有   线程正在使用中,队列已满,将拒绝任务。如   队列减少,活动线程数也减少。

     

用户预期的方式:随着请求的进入,将创建线程   到10,然后将任务添加到队列,直到队列达到100   他们被拒绝的那一点。线程数将重命名为   最大,直到队列为空。当队列为空时,线程将   消失,直到剩下corePoolSize为止。

因此Java等待最后一秒钟,直到队列耗尽以创建新线程...

答案 1 :(得分:1)

是的,按照@Oleg和您尝试的实现:

  

新的ThreadPoolExecutor(10、20、60L,TimeUnit.SECONDS,新的ArrayBlockingQueue(600));

在这里, 10是corePoolSize -表示Jvm将为前10个任务的新任务创建新线程。其他任务将被添加到队列中,直到队列已满(600个任务)。

20是maxPoolSize -JVM最多可以创建20个线程。意味着如果已经有10个任务/线程正在运行并且队列中有600个待处理的任务已满,并且如果队列中又有一个新的请求/任务到达,那么JVM将创建最多20个新线程(总线程数=先前的10 +新的10) ;

新的ArrayBlockingQueue(600) =是队列的总大小-它可以在其中排队600个任务。

所有20个线程都运行后,如果新任务到达,则该新任务将被拒绝。

[FROM DOC] SUN内部创建线程的规则:

  • 如果线程数少于corePoolSize,则创建一个新的Thread以运行新任务。
  • 如果线程数等于(或大于)corePoolSize,则将任务放入队列。
  • 如果队列已满,并且线程数少于maxPoolSize,请创建一个新线程以在其中运行任务。
  • 如果队列已满,并且线程数大于或等于maxPoolSize,则拒绝任务。

希望有帮助。