Существует два подхода, позволяющие избежать занятых циклов / снов.
Используйте поток для каждого клиентского соединения и просто вызовите каждый поток read
. Это блокирует поток, пока клиент не отправит некоторые данные, но это не проблема, потому что он не блокирует потоки, обрабатывающие других клиентов.
Использовать селекторы каналов Java NIO. Это позволяет потоку ждать, пока один из набора каналов (в данном случае сокетов) не получит данные для чтения. На этом есть раздел Oracle Java Tutorials .
Из этих двух подходов второй наиболее эффективен с точки зрения общего использования ресурсов. (Подход «поток-на-клиент» использует много памяти для стеков потоков и ЦП для издержек на переключение потоков.)
Занятые циклы, которые многократно вызывают (скажем) InputStream.available()
, чтобы увидеть, есть ли какой-либо ввод, ужасно неэффективны. Вы можете сделать их менее неэффективными, замедляя опрос с помощью вызовов Thread.sleep(...)
, но это побочным эффектом делает службу менее отзывчивой. Например, если вы добавляете 1-секундный сон между каждым набором опросов, эффект, который увидит каждый клиент, состоит в том, что сервер , как правило, , задерживает 1 секунду перед обработкой каждого запроса. Предполагая, что эти запросы являются нажатиями клавиш, и ответы повторяют их, чистый результат - ужасно запаздывающий сервис.