我已经实现了一个Socket Listener来读取从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();
}
}
这是我的Runnable类:
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);
}
}
}
}
答案 0 :(得分:6)
如果readLine()
返回null
,则必须关闭套接字,退出读取循环,并忘记该客户端。你在EOS旋转。
答案 1 :(得分:4)
不是为每个传入请求创建新线程,而是使用线程池:
private ExecutorService executor = Executors.newFixedThreadPool(15);
// ...
gd = new GPSData(serverSocket.accept());
executor.submit(gd);
这样,您将消除在接收请求时创建无限制线程的开销,而不是在打开套接字端口以接收请求之前创建有限的线程。
另外,正如@EJB所说,只要从null
收到readLine()
作为流结束(EOS)的指示符,就退出客户端for循环。
答案 2 :(得分: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。