1

我不确定我的描述是否正确,但这里有解释。

我有一个客户端消息处理系统,看起来很像这样:(它在单独的线程中运行)

public void run() {
    String line;

    while(true)
    {
        try
        {
            while ((line = reader.readLine( )) == null) { Thread.sleep(10); }; 

            if (line.toUpperCase().startsWith("PING ")) {
                // Autorespond to server pings
                server.Write("PONG " + line.substring(5));
            }
            else {
                setChanged();
                notifyObservers(line);
            }
        }
        catch (Exception e)
        {
            //do something here
        }
    }

}

我真的,真的,想做的是替换这条线:while ((line = reader.readLine( )) == null) { Thread.sleep(10); }用别的东西,别的东西,这不是一个本质上的无限循环。

代码分解 循环永远直到行包含一些数据。如果是 ping 请求,则自动响应并重新开始。如果不是,将收到的消息通知观察者,然后重新开始。

观察者模型有效,不用担心。阅读器实际上确实可以正常工作……但是它消耗了很多处理器,它们处于无限循环中,检查事物。

问题 我如何使用某种并发、等待或任何模型,以便线程本身将简单地等待,直到 BufferedReader 实际有数据要读取?有没有办法做到这一点,或者Thread.Sleep(10)我实际上添加了最好的方法来防止无限期地吃掉我所有的处理器。

4

2 回答 2

4

我真正想要做的是替换这一行: while ((line = reader.readLine( )) == null) { Thread.sleep(10); } 与其他东西,其他任何东西,这不是本质上的无限循环。

你在这里有一个基本的误解。readLine() 确实阻塞,直到数据出现。它仅null在您到达流结束时返回,即文件结束或对等方已关闭连接。你不需要睡觉;您只需要反转测试!= null并将处理数据的代码放入循环中。

目前,您正在循环结束时在循环中旋转这将永远不会终止。

于 2013-10-14T03:43:00.833 回答
-1

ifreader与套接字/(未知长度流)相关联,因此没有行尾,因此没有返回 null。你知道这里最重要的是协议,客户端和服务器都应该知道数据是如何发送和接收的,例如HTTP协议头大小是未知的,所以服务器和客户端都期望一个空行(\r\n)表示结束的标题。所以首先你需要有自己的协议,其次要注意空值。

public void run() {
    String line;

    while(true)
    {
        try
        {
            while (true) {
            line = reader.readLine( );//it throws exception if client/server closes the stream.
            if(line==null){return;/*break;*/}
            if (line.toUpperCase().startsWith("PING ")) {
                // Autorespond to server pings
                server.Write("PONG " + line.substring(5));
            }
            else {
                setChanged();
                notifyObservers(line);
            }
        }
        catch (Exception e)
        {
            //do something here
        }
      }
    }

}

也没有必要Thread.sleep(),因为 I/O 操作会阻塞,直到一些数据可用,即使是 2 年。

于 2013-10-14T09:03:49.250 回答