Опасно ли запускать потоки в Java и не ждать их (с помощью .join ())? - PullRequest
1 голос
/ 26 февраля 2011

При записи многопоточного интернет-сервера в java основной поток запускает новые для параллельной обработки входящих запросов.

Есть ли проблемы, если основной поток не ожидает (с .join()) дляих?(Очевидно, абсурдно создавать новую тему, а затем ждать ее).

Я знаю, что в практической ситуации вы должны (или «должны»?) Реализовать пул потоков, чтобы «повторно использовать» их для новых запросов, когда они простаивают.

Но для небольших приложений мы должны использовать пул потоков?

Ответы [ 5 ]

8 голосов
/ 26 февраля 2011

Вам не нужно ждать темы.

Они могут либо завершить работу самостоятельно (если они были созданы для выполнения одной конкретной задачи), либо работать бесконечно (например, в среде серверного типа).

Они должны обрабатывать прерывания и отвечать на запросы на отключение.См. эту статью о том, как это сделать правильно.

Если вам нужен набор потоков, я бы использовал пул и executor методы, так как они будут следить за потокомуправление ресурсами для вас.Если вы пишете многопоточный сетевой сервер, я бы исследовал использование, скажем, контейнера сервлета или инфраструктуры, такой как Mina .

1 голос
/ 26 февраля 2011

Единственная проблема в вашем подходе состоит в том, что он не масштабируется сверх определенной частоты запросов. Если запросы поступают быстрее, чем ваш сервер может их обработать, количество потоков будет непрерывно расти. Поскольку каждый поток добавляет некоторые накладные расходы и использует процессорное время, время обработки каждого запроса будет увеличиваться, поэтому проблема будет усугубляться (поскольку число потоков возрастает еще быстрее). В конце концов, ни один запрос не сможет быть обработан больше, потому что все время ЦП тратится на накладные расходы. Возможно, ваше приложение потерпит крах.

Альтернативой является использование ThreadPool с фиксированной верхней границей потоков (которая зависит от мощности оборудования). Если запросов больше, чем потоки могут обработать, некоторым запросам придется слишком долго ждать в очереди запросов и произойдет сбой из-за истечения времени ожидания. Но приложение по-прежнему сможет обрабатывать оставшиеся входящие запросы.

К счастью, Java API уже обеспечивает хорошую и гибкую реализацию ThreadPool, см. ThreadPoolExecutor . Использовать это, вероятно, даже проще, чем реализовать все с помощью оригинального подхода, поэтому нет причин не использовать его.

1 голос
/ 26 февраля 2011

Thread.join () позволяет вам ждать окончания потока, что в основном противоречит тому, что вы хотите при запуске нового потока.В общем, вы начинаете новый поток, чтобы делать вещи параллельно с исходным потоком.

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

0 голосов
/ 26 февраля 2011

Я хотел бы собрать основные идеи этого интересного (для меня) вопроса.

  1. Я не могу полностью согласиться с «вам не нужно ждать темы»,Только в том смысле, что если вы не присоединяетесь к потоку (и не имеете указателя на него) после завершения потока, его ресурсы освобождаются (верно? Я не уверен).

  2. Использование пула потоков необходимо только для того, чтобы избежать накладных расходов на создание потоков, поскольку ...

  3. Вы можете ограничить число параллельных работающих потоков с учетом общих переменных (и без пула потоков), сколько из них было запущено, но еще не завершено.

0 голосов
/ 26 февраля 2011

Вам следует подождать своих потоков, если вам нужны их результаты или необходимо выполнить некоторую очистку, которая возможна только после того, как все они мертвы, в противном случае - нет.

Для пула потоков: я бы использовал его, когда у вас есть нефиксированное количество задач для выполнения, т. Е. Если число зависит от ввода.

...