0

500を超えるプレーヤーを同時に接続すると、(マルチスレッド)サーバーでこの奇妙な問題が発生します。PrinterWriterがflush()またはprint()を完了するのに100秒以上(2分)かかることがあります。

コードは次のとおりです。

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秒ごとにラグを開始します。追加しないと、理由もなくランダムなプレーヤーがラグを開始します。

誰かが何か考えを持っていますか?これはどこから来たのですか?私は何をすべきか?

4

2 に答える 2

1

プリントライターはソケットの出力ストリームにラップされているので、ソケットの出力バッファーがいっぱいであると推測して言います。したがって、書き込み/フラッシュ呼び出しは、送信されるメッセージを収容するのに十分なスペースがバッファーにあるまでブロックされます。

ソケット送信バッファーは、データがクライアントに送信できるよりも速く(またはクライアントが受信できるよりも速く)書き込まれている場合、いっぱいになる可能性があります。

編集:

PSスケーラビリティの問題がある場合は、java.nio(この場合、単一のスレッドが保留中のデータを持つソケットで操作を検出して実行できる)の代わりにjava.io(ソケットごとに1つのスレッドが必要)を使用していることが原因である可能性があります)。nioは、多数の接続に拡張する必要があるアプリケーションをサポートすることを目的としていますが、プログラミングモデルはより困難です。

于 2011-07-30T03:42:24.750 に答える
0

その理由は、send()メソッドが静的であるため、任意のソケットに書き込むすべてのスレッドが、含まれているクラスオブジェクトで同期されているためです。非静的にすると、同じソケットに書き込んでいるスレッドのみが同期されます。

于 2011-07-30T03:49:18.517 に答える