Создание большого количества потоков никогда не является хорошей идеей (и когда вы создаете слишком много потоков, у вас все равно может не хватить памяти).
Обычно Джерси необходимо создать один поток для каждого запроса. И это похоже на тот случай, использую ли я async()
(где Jersey создает потоки для меня - я исследовал это в отладчике) или не (где я, очевидно, должен создать темы сам).
Итак, вот одна конкретная ситуация, когда этого недостаточно:
Я отправляю HTTP-сообщения на удаленные серверы со скоростью до 500 запросов в секунду. Но поскольку для получения ответа может потребоваться некоторое время (я рассчитываю до 30 секунд), общее количество потоков может легко достигать нескольких тысяч (в этот момент обычно происходит сбой процесса JVM). Более того, создавать столько тем просто безумие. На самом деле это должно быть проще простого для доступных ресурсов процессора/сети/ОС, чтобы справиться с этой нагрузкой.
Итак, что я хотел бы сделать, так это просто запустить запросы и получить информацию от ОС, когда придет ответ HTTP.
- Как сказано выше, простое использование
target.request(...).async()....
не помогает (потому что Джерси просто порождает свои собственные потоки). - Кроме того, ограничение количества потоков через
new ClientConfig().property(ClientProperties.ASYNC_THREADPOOL_SIZE, 10)
вообще не помогает, потому что это означает, что за раз будет отправлено не более 10 запросов, что явно не то, что я хочу (это просто нагромодит очередь).
Я экспериментировал с new ClientConfig().connectorProvider(new GrizzlyConnectorProvider())
, чтобы получить поддержку NIO, но вообще не увидел никакой разницы в поведении.
Итак, есть ли способ запустить запрос, не создавая один дополнительный поток для каждого запроса?
sysctl kern.num_taskthreads
показываетkern.num_taskthreads: 2048
- и кажется, что Oracle JVM фактически использует потоки ядра (интересно). - person Chris Lercher   schedule 03.10.2014