我的程序上有一个侦听器线程,它只是在等待服务器的输入。因此,他收到一条消息,将其放入队列中,然后等待另一条消息。因此,无法按照其他类似主题中提出的方式关闭它,因为他需要在测试While条件之前从服务器接收消息。
这里是:
public class Listener implements Runnable{
private Socket socket;
private ObjectInputStream ois;
public Listener(Socket socket) {
this.socket = socket;
try {
this.ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
while(!socket.isClosed()) {
String type = ois.readUTF();
System.out.println("received: " +type);
main.queue.put(type);
}
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
所以基本上,当我关闭套接字时,ois.readUTF将抛出EOFException。 我该怎么做才能正确停止此流而不会出现此异常?
我发现的唯一方法是,当客户端想要停止连接(并因此关闭套接字)时,他可以向服务器发送一条消息(例如“再见”或其他),然后服务器将回答“再见”,当我的听众收到再见时,他将关闭套接字,这将使他退出while循环并停止。我认为应该运作良好。但是我想知道是否还有另一种方法(某种程度上我对我的想法不太满意)。
答案 0 :(得分:1)
最好的方法是使用NIO API提供的非阻塞IO API。这将需要对这段代码进行不重要的更改。
最简单的方法是在关闭套接字之前设置一些标志isFinishing
。然后,等待线程应检查该标志是否在catch子句中设置。如果是这种情况,则可以放心地忽略EOFException
。如果您采用这种方式,请确保isFinishing
已正确同步(易失性或更佳的CountDownLatch
)。