1

マルチスレッド サーバー プログラムの接続を開いたままにしようとしています。ボタンを押すと、接続されているすべてのクライアントにテスト メッセージが送信されます。

public void run() {
    try {
        Scanner in = new Scanner(socket.getInputStream());
        PrintWriter out = new PrintWriter(socket.getOutputStream());
        readUpdate(out, in);
        while(true){sendUpdate(out);}
    } catch (Exception e) {
        e.printStackTrace();
    }
}

多くの CPU を使用します。

これが私の sendUpdate メソッドです。

private void sendUpdate(final PrintWriter out) {
    new Thread(new Runnable() {

        public void run() {
            if(Server.send) {
                try {
                    if (Server.command != "idle") {
                        System.out.println("Sending");
                        out.println("!msg@" + Server.command);
                        out.flush();
                        Server.send = false;
                        Thread.sleep(100);
                    }
                } catch (Exception ex) {
                }
            }
        }
    }).start();
}

誰かが接続を開いたままにし、データを送信する準備ができているのを手伝ってくれるなら、私はそれを感謝します.

4

1 に答える 1

1

サーバーがメッセージを開始でき、クライアントも同様にメッセージを開始できる場合は、おそらく別のスレッドで読み取りと書き込みを行う必要があります。1 つのスレッドは、次のクライアント要求でブロックし、サーバー側の処理を行い、クライアントに応答してから再度ブロックできる、要求応答スタイルの通信に適しています。

しかし、2 つの別々の条件 (クライアントからのメッセージの受信とサーバー上のボタンのクリック) でブロックする必要がある場合は、2 つの別々のスレッドが必要です。そうしないと、いずれかの条件が真であるかどうかを確認するために、スレッドを繰り返し起動する必要があることに気付くでしょう。

したがって、2 つのスレッドを作成し、1 つにScanner(readUpdateロジックを実行する) あなたの、もう 1 つにあなたのPrintWriter. 出力ハンドラは次のようになります。

public class WriteHandler implements Runnable {
    private final PrintWriter out;
    private final BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();

    //initialize the above in a constructor;

    public void run() {
       while(true) {
          String nextMessageToWrite = messageQueue.poll();
          out.println(nextMessageToWrite);
       }
    }

    public void send(String message) {
        messageQueue.add(message);
    }
}

これは、check-sleep ループよりもはるかに優れた同時実行メカニズムであるブロッキング キューを使用します。次に、ボタンをクリックすると、次のようになります。

public void actionPerformed() {
    for ( WriteHandler handler : handlers ) {
        handler.send("PING!");
    }
}
于 2012-07-08T17:45:26.163 に答える