Какова функция ThreadPoolExecutor MaximumPoolSize в Java - PullRequest
0 голосов
/ 25 декабря 2018

Я борюсь с чем-то глупо простым ...

Мой настоящий проект страдал от неизвестной проблемы целую вечность, я решил создать очень простой тест, и я испугался результатов ....

Вот тест:

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 голосов
/ 25 декабря 2018

Да, в соответствии с @Oleg и используемой вами реализацией:

new ThreadPoolExecutor (10, 20, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue (600));

Здесь 10 - это corePoolSize - означает, что Jvm создаст новый поток для новой задачи для первых 10 задач.и другие задачи будут добавляться в очередь до тех пор, пока очередь не заполнится (600 задач).

20 - это maxPoolSize - JVM может создавать до 20 потоков.Означает, что если уже запущено 10 задач / потоков и очередь заполнена 600 ожидающими задачами, и если в очередь поступает еще один новый запрос / задача, то JVM создаст новый поток до 20 (общее количество потоков = предыдущие 10 + новые 10);

new ArrayBlockingQueue (600) = - это общий размер очереди - он может поставить в очередь 600 задач в нем.

после запуска всех 20 потоков и если новая задачато после этого новая задача будет отклонена.

[FROM DOC] Правила внутреннего создания потоков с помощью SUN:

  • Если число потоков меньше, чем corePoolSize, создайте новыйПоток для запуска новой задачи.
  • Если число потоков равно (или больше) corePoolSize, поместите задачу в очередь.
  • Если очередь заполнена, и числопотоков меньше, чем maxPoolSize, создайте новый поток для запуска задач.
  • Если очередь заполнена, а число потоков больше или равно maxPoolSize, отклоните задачу.

Надеюсь, это полезно.

0 голосов
/ 25 декабря 2018

Как указывает @Oleg, пул работает нормально, но есть детали реализации, о которых я не знал.

Дополнительные потоки будут создаваться, только если очередь задач FULL

эта статья объясняет лучше: 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 ждет последнюю секунду, прежде чем ваша очередь вылетит, чтобы создать новый поток ...

...