gpt4 book ai didi

java - 使用 JAVA 从 Socket 读取数据时减少 CPU 开销

转载 作者:行者123 更新时间:2023-12-01 23:53:36 24 4
gpt4 key购买 nike

我有两个线程会增加 CPU 开销。1. 以同步方式从socket读取。2.等待接受其他客户端的连接

问题1,我只是想读取来自客户端的任何数据,并且我无法使用readline,因为传入的数据具有换行符,我将其标记为了解消息的 header 末尾。所以我在线程中使用这种方式,但它增加了CPU开销

 public static String convertStreamToString(TCPServerConnectionListner socket) throws UnsupportedEncodingException, IOException, InterruptedException {

BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getSocket().getInputStream()));
// At this point it is too early to read. So it most likely return false
System.out.println("Buffer Reader ready? " + reader.ready());
// StringBuilder to hold the response
StringBuilder sb = new StringBuilder();
// Indicator to show if we have started to receive data or not
boolean dataStreamStarted = false;
// How many times we went to sleep waiting for data
int sleepCounter = 0;
// How many times (max) we will sleep before bailing out
int sleepMaxCounter = 5;
// Sleep max counter after data started
int sleepMaxDataCounter = 50;
// How long to sleep for each cycle
int sleepTime = 5;
// Start time
long startTime = System.currentTimeMillis();
// This is a tight loop. Not sure what it will do to CPU
while (true) {
if (reader.ready()) {
sb.append((char) reader.read());
// Once started we do not expect server to stop in the middle and restart
dataStreamStarted = true;
} else {
Thread.sleep(sleepTime);
if (dataStreamStarted && (sleepCounter >= sleepMaxDataCounter)) {
System.out.println("Reached max sleep time of " + (sleepMaxDataCounter * sleepTime) + " ms after data started");
break;
} else {
if (sleepCounter >= sleepMaxCounter) {
System.out.println("Reached max sleep time of " + (sleepMaxCounter * sleepTime) + " ms. Bailing out");
// Reached max timeout waiting for data. Bail..
break;
}
}
sleepCounter++;
}

}
long endTime = System.currentTimeMillis();

System.out.println(sb.toString());
System.out.println("Time " + (endTime - startTime));

return sb.toString();
}

问题2,我不知道最好的方法是什么,我只是有一个线程不断等待其他客户端并接受它。但这也需要大量的CPU开销。

 // Listner to accept any client connection
@Override
public void run() {

while (true) {
try {
mutex.acquire();
if (!welcomeSocket.isClosed()) {
connectionSocket = welcomeSocket.accept();
// Thread.sleep(5);
}


} catch (IOException ex) {
Logger.getLogger(TCPServerConnectionListner.class.getName()).log(Level.SEVERE, null, ex);
} catch (InterruptedException ex) {
Logger.getLogger(TCPServerConnectionListner.class.getName()).log(Level.SEVERE, null, ex);
}
finally
{
mutex.release();
}

}
}
}

分析器图片也会有所帮助,但我想知道为什么 SwingWorker 线程需要那么多时间? enter image description here

更新问题一的代码:

    public static String convertStreamToString(TCPServerConnectionListner socket) throws UnsupportedEncodingException, IOException, InterruptedException {

byte[] resultBuff = new byte[0];
byte[] buff = new byte[65534];
int k = -1;
k = socket.getSocket().getInputStream().read(buff, 0, buff.length);
byte[] tbuff = new byte[resultBuff.length + k]; // temp buffer size = bytes already read + bytes last read
System.arraycopy(resultBuff, 0, tbuff, 0, resultBuff.length); // copy previous bytes
System.arraycopy(buff, 0, tbuff, resultBuff.length, k); // copy current lot
resultBuff = tbuff; // call the temp buffer as your result buff

return new String(resultBuff);
}

}
![snapshot][2]

最佳答案

只需摆脱 ready() 调用并阻塞即可。在 ready() 为 false 时所做的一切实际上完全是浪费时间,包括 sleep 。 read() 将阻塞正确的时间。 sleep() 不会。您要么 sleep 时间不够长,这会浪费 CPU 时间,要么 sleep 时间太长,这会增加延迟。偶尔你可能会睡在正确的时间,但这是100%的运气,而不是良好的管理。如果您想要读取超时,请使用读取超时。

关于java - 使用 JAVA 从 Socket 读取数据时减少 CPU 开销,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15965984/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com