Лучший способ настроить Threadpool для клиентского приложения Java RIA - PullRequest
0 голосов
/ 16 декабря 2009

У меня есть Java-клиент, который обращается к нашей стороне сервера по HTTP, делая несколько небольших запросов для загрузки каждой новой страницы данных. Мы поддерживаем пул потоков для обработки всей обработки, не связанной с пользовательским интерфейсом, поэтому любые фоновые задачи на стороне клиента и любые задачи, которые хотят установить соединение с сервером. Я изучал некоторые проблемы с производительностью, и я не уверен, что мы настроили наш пул потоков настолько хорошо, насколько это возможно. В настоящее время мы используем ThreadPoolExecutor с размером пула ядра 8, мы используем LinkedBlockingQueue для рабочей очереди, поэтому максимальный размер пула игнорируется. Нет сомнений в том, что в любой ситуации нет простого ответа, но есть ли лучшие практики. Мое мышление на данный момент

1) Я переключусь на использование SynchronousQueue вместо LinkedBlockingQueue, чтобы пул мог увеличиваться до значения максимального размера пула. 2) Я установлю максимальный размер пула неограниченным.

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

Какие-либо предложения, лучшие практики или полезные ссылки? Ура, Robin

Ответы [ 4 ]

1 голос
/ 16 декабря 2009

Как сказал alphazero , если у вас возникло узкое место, число ожидающих заданий на стороне клиента будет продолжать расти независимо от того, какой подход вы используете.

Реальный вопрос в том, как вы хотите справиться с узким местом. Или, более правильно, как вы хотите, чтобы ваши пользователи справились с узким местом.

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

Если вы используете LinkedBlockingQueue.offer() в ограниченной очереди, вы сразу получите ответ, в котором говорится, что очередь заполнена, и можете предпринять такие действия, как отключение определенных функций приложения, появление диалогового окна, что угодно. Это, однако, потребует дополнительной работы с вашей стороны, особенно если запросы могут быть отправлены из нескольких мест. Я бы посоветовал, если у вас его еще нет, вы создаете слой с поддержкой графического интерфейса поверх очереди сервера, чтобы обеспечить общее поведение.

И, конечно же, никогда не звоните LinkedBlockingQueue.put() из потока событий (если вы не возражаете против зависшего клиента, то есть).

1 голос
/ 16 декабря 2009

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

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

Обе параллельные очереди в JDK являются высокопроизводительными; выбор действительно сводится к семантике использования. Если у вас неблокирующая сантехника, то более естественно использовать неблокирующую очередь. Если вы этого не сделаете, то использование блокирующих очередей имеет больше смысла. (Вы всегда можете указать Integer.MAX_VALUE в качестве ограничения). Если обработка FIFO не является обязательной, убедитесь, что вы не указали справедливый порядок, поскольку это повлечет за собой существенное снижение производительности.

1 голос
/ 16 декабря 2009

Звучит так, что вам, вероятно, лучше ограничить размер очереди: продолжает ли ваше приложение работать правильно, когда в очереди находится много запросов (приемлемо ли, чтобы все задачи были поставлены в очередь в течение длительного времени, некоторые из них более важны для другие)? Что произойдет, если остаются все еще поставленные в очередь задачи и пользователь выходит из приложения? Если очередь становится очень большой, есть ли вероятность того, что сервер наверстает упущенное (достаточно скоро), чтобы полностью скрыть проблему от пользователя?

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

Для реальных фоновых задач держите отдельный пул с более длинной очередью, но не бесконечной. Определите изящное поведение для этого пула, когда он увеличивается или когда пользователь хочет выйти, но остаются задачи, что должно произойти?

0 голосов
/ 16 декабря 2009

Почему бы не создать неограниченную очередь, а отклонить задачи (и, возможно, даже сообщить пользователю, что сервер занят (зависит от приложения!)), Когда очередь достигает определенного размера? Затем вы можете зарегистрировать это событие и выяснить, что произошло на стороне сервера для резервного копирования. Кроме того, если вы не подключаетесь к нескольким удаленным серверам, вероятно, нет особого смысла в том, чтобы в пуле было более пары потоков, хотя это зависит от вашего приложения и от того, что оно делает, и с кем оно общается.

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

...