Пул потоков Java по сравнению с новым потоком в высоком сценарии запроса

В вашей схеме слияние будет ускоренным, что означает, что мастер HEAD будет просто ссылаться на разработку HEAD: его содержание будет идентичным тому, что вы объединяете, потому что эволюция не была сделана в мастер, а разработка была обновлена.

Даже если вы сделаете git merge --no-ff, результирующий коммит слияния будет идентичен для разработки HEAD.

Если содержание точно одинаковое, прошедшие тесты должны выдержать.

8
задан Arne Claassen 10 March 2009 в 16:17
поделиться

4 ответа

С конфигурацией:

new ThreadPoolExecutor(10, 100, 30, TimeUnit.SECONDS, 
        new ArrayBlockingQueue<Runnable>(100))

Затем, после того как 10 потоков одновременно обрабатывают запросы, дальнейшие запросы добавляются к очереди, если она не достигает 100 запросов в очереди, в котором времени она начнет новые дискуссии создания, если уже не будет 100 потоков, когда обработка команды будет отклонена.

Раздел javadocs ThreadPoolExecutor (скопированный ниже), может стоить другого чтения.

На основе их и Вашей очевидной готовности иметь 100 выполнений потоков и Ваше требование принять все запросы, обрабатывая их в конечном счете.. Я рекомендовал бы пробовать изменения как:

new ThreadPoolExecutor(100, 100, 0, TimeUnit.SECONDS, 
        new LinkedBlockingQueue<Runnable>())

Который, несущественно, является тем, от чего Вы добрались бы Executors.newFixedThreadPool(100);


Организация очередей

Любой BlockingQueue может использоваться, чтобы передать и содержать отправленные задачи. Использование этой очереди взаимодействует с калибровкой пула:

  • Если меньше, чем потоки corePoolSize работают, Исполнитель всегда предпочитает добавлять новый поток вместо организации очередей.
  • Если corePoolSize или больше потоков работают, Исполнитель всегда предпочитает ставить запрос в очередь вместо того, чтобы добавить новый поток.
  • Если бы запрос не может быть поставлен в очередь, новый поток создается, если это не превысило бы maximumPoolSize, в этом случае, задача будет отклонена.

Существует три общих стратегии организации очередей:

  1. Прямые передачи. Хорошим выбором по умолчанию для очереди заданий является SynchronousQueue это руки прочь от задач к потокам, иначе не содержа их. Здесь, попытка поставить задачу в очередь перестанет работать, если никакие потоки не будут сразу доступны для выполнения ее, таким образом, новый поток будет создан. Эта политика избегает тупиков при обработке наборов запросов, которые могли бы иметь внутренние зависимости. Прямые передачи обычно требуют, чтобы неограниченный maximumPoolSizes избежал отклонения новых отправленных задач. Это в свою очередь допускает возможность неограниченного роста потока, когда команды продолжают прибывать в среднем быстрее, чем они могут быть обработаны.
  2. Неограниченные очереди. Используя неограниченную очередь (например, LinkedBlockingQueue без предопределенной способности) вызовет новые задачи ожидать в очереди, когда все потоки corePoolSize будут заняты. Таким образом, не больше, чем corePoolSize потоки будет когда-либо создаваться. (И значение maximumPoolSize поэтому не имеет никакого эффекта.) Это может быть соответствующим, когда каждая задача абсолютно независима от других, таким образом, задачи не могут влиять на каждую казнь других; например, в сервере веб-страницы. В то время как этот стиль организации очередей может быть полезным в сглаживании переходных пакетов запросов, это допускает возможность неограниченного роста очереди заданий, когда команды продолжают прибывать в среднем быстрее, чем они могут быть обработаны.
  3. Ограниченные очереди. Ограниченная очередь (например, ArrayBlockingQueue) помогает предотвратить исчерпание ресурса, когда она используется с конечным maximumPoolSizes, но может быть более трудной настроить и управлять. Размеры очереди и максимальные размеры пула могут быть обменяны друг за друга: Используя многочисленные очереди и маленькие пулы минимизирует использование ЦП, ресурсы ОС и контекстное переключение наверху, но может привести к искусственно низкой пропускной способности. Если задачи часто блокируются (например, если они - связанный ввод-вывод), система может планировать время для большего количества потоков, чем Вы иначе позволяете. Использование малочисленных очередей обычно требует больших размеров пула, который сохраняет центральные процессоры более занятыми, но может встретиться с недопустимым планированием наверху, которое также уменьшает пропускную способность.
12
ответ дан 5 December 2019 в 10:05
поделиться

Реализация Sun Thread, хотя намного быстрее, чем он раньше был, действительно имеет блокировку. IIRC, ArrayBlockingQueue не должен на самом деле блокировать вообще, когда занятый. Поэтому это - время профилировщика (или даже только некоторые ctrl-\s или jstacks).

Системная нагрузка просто говорит Вам, сколько потоков ставится в очередь. Это не обязательно очень полезно.

1
ответ дан 5 December 2019 в 10:05
поделиться

измерение, измерение, измерение! Где это проводит время? Что должно произойти, когда Вы создаете свое Выполнимое? Выполнимое имеет что-нибудь, что могло блокироваться или задерживаться в инстанцировании? Что происходит во время той задержки?

Я - на самом деле крупный сторонник продумывания вещей в целом, но этот вид случая, с неожиданным поведением как это, просто должен иметь некоторые измерения.

Каковы среда выполнения, версия JVM и архитектура?

4
ответ дан 5 December 2019 в 10:05
поделиться

Я просто сделал это с частью моего собственного кода. Я использовал профилировщика Netbeans для превращения реализации пула потоков, которую я использовал. Необходимо смочь сделать то же самое с Визуальным VM, но я еще не попробовал это.

0
ответ дан 5 December 2019 в 10:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: