3

GPS から送信されたデータを読み取るソケット リスナーを実装しましたが、CPU の 90% を消費しています。これが私のコードであることはわかっていますが、どこにあるのかわかりません。

これは私のメインクラスです:

public class PortToDB {

    ServerSocket serverSocket = null;

    public void listenSocket(){
        try{
            serverSocket = new ServerSocket(50000);
        } catch (IOException e) {
            System.out.println("Could not listen on port 50000. " + e);
            System.exit(-1);
        }

        while(true){
            GPSData gd;
            try{
                gd = new GPSData(serverSocket.accept());
                Thread t = new Thread(gd);
                t.start();
            } catch (IOException e) {
                System.out.println("Accept failed: 50000. " + e);
                System.exit(-1);
            }
        }
    }

    public static void main(String[] args) {    
        PortToDB portToDb = new PortToDB();
        portToDb.listenSocket();
    }
}

これは私の実行可能なクラスです:

class GPSData implements Runnable {

    private Socket client;
    DBHandler dbhandler = new DBHandler();

    GPSData(Socket client) { this.client = client; }

    public void run(){
        String line;
        BufferedReader in = null;

    try{
        in = new BufferedReader(new InputStreamReader(client.getInputStream()));
    } catch (IOException e) {
        System.out.println("in or out failed");
        System.exit(-1);
    }

    while(true){
      try{
          if((line = in.readLine()) != null){
              dbhandler.dbInsert(line);
          }
      } catch (IOException e) {
          System.out.println("Read failed");
          System.exit(-1);
      }
    }
  }
}
4

3 に答える 3

6

readLine()返された場合nullは、ソケットを閉じ、読み取りループを終了し、そのクライアントを忘れる必要があります。あなたはEOSで回転しています。

于 2013-02-27T21:22:55.430 に答える
4

着信リクエストごとに新しいスレッドを作成する代わりに、スレッド プールを使用します。

private ExecutorService executor = Executors.newFixedThreadPool(15);

// ...

gd = new GPSData(serverSocket.accept());
executor.submit(gd);

このようにして、リクエストの受信時に無制限のスレッドを作成し、代わりにソケット ポートを開いてリクエストを受信する前に制限付きのスレッドを作成するというオーバーヘッドを排除します。


また、@EJB が言ったように、ストリームの終わり (EOS) のインジケータとして受信nullするたびに、クライアントの for ループを終了します。readLine()

于 2013-02-27T21:01:45.937 に答える
0

私の質問に答えてくれたすべての人に感謝します。

Eng.Fouad と EJP の提案を組み合わせることで、これを解決しました。

これは私のコードで変更したものです:

実行者:

    private ExecutorService executor = Executors.newFixedThreadPool(15);

    try{
        gd = new GPSData(serverSocket.accept());
        executor.submit(gd);
    }

ループ制御:

    try{            
        while((line = in.readLine()) != null){         
        dbhandler.dbInsert(line);
        }
    }

現在、プロセスは0%のままです:)。

EJP と Eng.Fouad に感謝します。

于 2013-02-27T21:56:45.050 に答える