3

我已经实现了一个套接字侦听器来读取从 GPS 发送的数据,但它消耗了我 90% 的 CPU。我知道这是我的代码造成的,但我看不到在哪里。

这是我的主要课程:

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);

这样,您将消除在接收请求时创建无限线程的开销,而是在打开套接字端口接收请求之前创建有限线程。


null此外,正如@EJB 所说,每当您收到来自readLine()作为流结束(EOS)的指示符时,退出客户端 for 循环。

于 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 回答