Java 套接字通信:线程挂起

Java 套接字通信:线程挂起,java,multithreading,sockets,communication,Java,Multithreading,Sockets,Communication,我有一个简单的套接字服务器(用于HL7通信)。当它在生产环境中运行的时间更长时,套接字线程会挂起并消耗大量CPU时间 这是侦听器线程的相关代码(简称): public void run() { try { serverSocket = new ServerSocket(port, backlog, bindAddress); serverSocket.setSoTimeout(timeout); // 1000 ms do {

我有一个简单的套接字服务器(用于HL7通信)。当它在生产环境中运行的时间更长时,套接字线程会挂起并消耗大量CPU时间

这是侦听器线程的相关代码(简称):

public void run() {
    try {
        serverSocket = new ServerSocket(port, backlog, bindAddress);
        serverSocket.setSoTimeout(timeout); // 1000 ms
        do {
            Socket socket = null;
            try {
                socket = serverSocket.accept();
            } catch (SocketTimeoutException to) {
                socket = null;
            } catch (InterruptedIOException io) {
                socket = null;
            } catch (IOException e) {
                logger.fatal("IO exception while socket accept", e);
                socket = null;
            }

            try {
                if (socket != null)
                    processConnection(socket);
            } catch (RuntimeException e) {
                logger.fatal("caught RuntimeException trying to terminate listener thread", e);
            }
        } while (running);
    } catch (IOException e) {
        logger.fatal("error binding server socket - listener thread stopped", e);
    }
}
此代码启动一个新线程以处理传入连接:

protected void processConnection(Socket socket) {
    Hl7RequestHandler requestHandler = createRequestHandler();
    requestHandler.setSocket(socket);
    requestHandler.start();
}
这是请求处理程序线程的代码(keepAlive设置为true):

当我在本地测试时,它运行良好

但在生产环境中,存在多个“挂起”的请求处理程序线程。“保持活动”是保持连接打开以等待更多消息的提示。(为了避免一直打开新的连接。)我假设inputReader.read()在超时1s后返回-1,这导致再次调用该方法。为什么这会占用所有的CPU时间

你有什么建议吗

提前感谢,,
马蒂亚斯

我能马上看到的一件事是:

         char c;
        do {
            c = (char)inputReader.read();
            if ((c == CARRIAGE_RETURN || c == START_OF_MESSAGE) &&
                message.length() == 0)
            else if (c != END_OF_MESSAGE && ((short)c) != -1)
                // ein Byte "Nutzlast"
                message.append(c);
        } while (c != END_OF_MESSAGE && ((short)c) != -1);
将inputReader.read()转换为char。read()返回一个int,一个有符号的值。将其强制转换为无符号值的char,如果有负号,则丢弃负号,这是一种缩小转换。那么,转换成短符号并不会使负号(如果有的话)重新出现。 尝试重写为:

         char c;
         int val;
        do {
            val = inputReader.read();
            // do this if you want, you don't have to
            c = (char) val;
            if ((c == CARRIAGE_RETURN || c == START_OF_MESSAGE) &&
                message.length() == 0)
            else if (c != END_OF_MESSAGE && ((short)c) != -1)
                // ein Byte "Nutzlast"
                message.append(c);
        } while (c != END_OF_MESSAGE && val != -1);
我又看了一遍你的循环,我很困惑

        char c;
        do {
            c = (char)inputReader.read();
            if ((c == CARRIAGE_RETURN || c == START_OF_MESSAGE) &&
                message.length() == 0)
            else if (c != END_OF_MESSAGE && ((short)c) != -1)
                // ein Byte "Nutzlast"
                message.append(c);
        } while (c != END_OF_MESSAGE && ((short)c) != -1);
你的if语句的逻辑令人困惑(至少对我来说)。 第一个if子句没有语句,甚至没有空语句。
你必须要有{}或一个;你的代码编译吗

非常感谢你的回答,我会彻底改变的。但是它能解释时间消耗吗?我按照你的建议修改了代码。情况是一样的-inputReader.read()返回-1并立即再次被调用。我最终得到了两个请求处理程序线程。第一个节点愉快地与(单个)对等节点一起工作,并接收和处理消息。第二个消耗了100%的cpu并无休止地循环(cpu负载1.0)。一段时间后(可能对等端终止),第三个线程出现,进一步增加了cpu负载…也许我会尝试socket.setKeepAlive(true)我发现:啊,你的cpu消耗?BufferedInputStream不是阻塞调用。它将立即返回,因为您没有退出循环,所以它将一次又一次地调用input.read()。
        char c;
        do {
            c = (char)inputReader.read();
            if ((c == CARRIAGE_RETURN || c == START_OF_MESSAGE) &&
                message.length() == 0)
            else if (c != END_OF_MESSAGE && ((short)c) != -1)
                // ein Byte "Nutzlast"
                message.append(c);
        } while (c != END_OF_MESSAGE && ((short)c) != -1);