リモートソケットを継続的に聴いて、指定された入力に対して反応する必要があります。JavaソケットリスナーCPU負荷100%
public void listen(String ip, int port) {
try (
Socket socketListener = new Socket(ip, port);
BufferedReader portReader = new BufferedReader(new InputStreamReader(socketListener.getInputStream()));
) {
while (true) {
while (!portReader.ready()) {
// Wait for next PORT message
}
Logger.log(LogComponent.SOCKET, "Event received");
}
}
}
私は上記のコードが100%のCPU負荷を使用しているので非常に間違っていますか?
デバッグ中は、while-!portreader-loopが悪意のある人であることがわかります。しかし、私が見つけた例のほとんどは同じようにそれをやっています。あなたのコメントを考慮し
EDIT#1
私は今のソリューションを次ています
try {
Socket SocketListener = new Socket(ip, port);
BufferedReader portReader =
new BufferedReader(
new InputStreamReader(SocketListener.getInputStream())
);
// We do not use common while(true)-pattern for reading the input.
// Instead, we check for new input 3 times a second.
ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
executor.scheduleAtFixedRate(() -> {
try {
processInput(portReader);
} catch (IOException e) {
e.printStackTrace();
}
}, 0, 333, TimeUnit.MILLISECONDS);
} catch (Exception exception) {
exception.printStackTrace();
}
そしてprocessInput(0)
は今、行動を行っています。 これは単純にThread.sleep()を使用するよりもパフォーマンスが向上しますが、理由はわかりません。
このアプローチを使用する場合:コードがソケットからメッセージをいくつか見逃している可能性がありますか?私はその間隔の間に意味する?
「while true」は、CPUが許す限り速く実行されます。したがって、ループを遅くするためには '遅延'が必要です。 1秒あたりの頻度を計算して、リモートソケットをチェックし、適切な遅延を挿入します。たとえば1/10秒待機すると、1秒あたり約10回のチェックが行われます(チェック時間を引いたもの)。 –
また、メッセージの終わりを示すバイトを提供する必要があります。あなたのコードが-1を返すことは決してありません。あなたはストリームを閉じる必要があります。 – MissingSemiColon
ブロッキング読み出しを実行できないのはなぜですか?読みやすさをテストするために 'Reader.ready()'を使うのは間違った設計です。ノンブロッキング動作が必要な場合は、SelectableChannelsやJava 7で導入された非同期入出力機能を使用することを検討してください。 –