我不确定如果我的描述正确,但这里有解释。
我有一个客户端消息处理系统,看起来很像这样:(它在一个单独的线程中运行)
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)
我实际上添加了最好的方法来避免无限制地吃掉我所有的处理器。
答案 0 :(得分:4)
我真的,真的,想要做的是替换这一行:while((line = reader.readLine())== null){Thread.sleep(10);用其他东西,其他东西,这不是一个本质上无限的循环。
你在这里有一个基本的误解。在显示数据之前,readLine()
会阻止。当您到达流末尾时,它只返回null
,即文件结束或对等方已关闭连接。你不需要睡觉;你只需要将测试反转到!= null
并将处理数据的代码放在循环中。
目前你正在 流的循环中旋转,这将永远不会终止。
答案 1 :(得分:-1)
如果reader
与套接字/(未知长度流)相关联,那么就没有行尾,因此没有返回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年也是如此。