Java DataInputStream.read () вызывает 20% -ное постоянное использование ЦП, будучи заблокированным. - PullRequest
1 голос
/ 30 июля 2011

У меня приложение на стороне сервера открывает поток сокетов для каждого подключенного клиента. У меня есть DataInputStream в каждом потоке, который вызывает read (byte [] array) для чтения данных. Я также установил время ожидания сокета на несколько минут. Основной код выглядит примерно так:

while (dataInputStream.read(array) != -1) { do something... }

Однако после нескольких часов работы в jconsole с плагином topthreads я вижу, что несколько клиентских потоков используют каждый процессор по 20% ish. Если я нажму на него, стек вызовов покажет, что поток заблокирован в приведенной выше строке в функции read ().

Я знаю, что функция read () обычно блокирует ожидание данных. При блокировке он потребляет мало циклов ЦП. Теперь он использует 20% ish каждый и мой сервер работает все медленнее, когда больше потоков имеют ту же проблему. Мой сервер получает около 5 запросов на соединение в секунду, и это происходит очень редко, поскольку в течение нескольких часов проблема возникает только у 5 потоков.

Я действительно смущен. Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 31 июля 2011

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

Я не использую точную технику, но эта ссылка должна дать некоторое представление ...

почему бы вам не попробовать использовать BufferedInputStream или любой из StreamReader s ... эти классы помогут в производительности.

вы можете попробовать использовать классы из пакета java.util.concurrent для улучшения обработки потоков (создание пула потоков поможет уменьшить общее потребление памяти, тем самым способствуя общей производительности системы) ... не уверен, что вы делаете это уже

0 голосов
/ 31 июля 2011
while (dataInputStream.read(array) != -1) { do something... }

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

Однако, если массив не очень маленький, я сомневаюсь, что вы действительно используете 20% CPUздесь.Скорее всего, здесь расходуется 20% от прошедшего времени .Блокировка чтения по сети не использует процессор.

...