PrintWriter очень медленно сбрасывает () и печатает ().Многопоточность и розетки - PullRequest
0 голосов
/ 30 июля 2011

У меня странная проблема с моим (многопоточным) сервером, когда у меня подключено более 500 игроков одновременно, для PrinterWriter требуется более 100 секунд или более (2 минуты), чтобы иногда завершить flush () или print ().

Вот код:

public static void send(Player p, String packet)
{   
    PrintWriter out = p.get_out();
    if(out != null && !packet.equals("") && !packet.equals(""+(char)0x00))
    {
        packet = Crypter.toUtf(packet);
        out.print((packet)+(char)0x00);
        out.flush();
    }
}

printWriter выглядит примерно так:

_in = new BufferedReader(new InputStreamReader(_socket.getInputStream()));
_out = new PrintWriter(_socket.getOutputStream());

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

У кого-нибудь есть идеи?Откуда это?Что мне делать?

Ответы [ 2 ]

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

Пишущий модуль печати обернут вокруг потока вывода сокета, поэтому я собираюсь угадать и сказать, что буфер вывода сокета заполнен, и поэтому вызов write / flush будет блокироваться, пока в буфере не будет достаточно места для размещения сообщения.послан.

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

Редактировать:

PS Если у вас проблемы с масштабируемостью, это может быть связано с использованием java.io (для которого требуется один поток на сокет) вместо java.nio (в этом случае один поток может обнаружитьи выполнить операции с теми сокетами, которые имеют данные в ожидании).nio предназначен для поддержки приложений, которые должны масштабироваться до большого количества соединений, но модель программирования более сложна.

0 голосов
/ 30 июля 2011

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

...