您不能简单地停止服务器。清理过程可能需要一段时间,因为您需要确保一致性。
想象一下数据库服务器,如果您在执行事务时将其关闭,则可能会使其数据不一致。这就是为什么它通常需要一段时间才能关闭服务器。
- 您必须先停止接受服务器中的新连接 。
- 然后您可以等待 当前工作线程完成 他们的工作,然后关闭 服务器并正式关闭。
- 或者你强制工作线程 关闭与
客户他们的连接(可能使用某种标志的
的建议)。这可能是 意味着一些清理,以保持数据 一致,例如恢复 传输或您在文件或内存中完成的任何类型的更改 。
根据我的理解,关闭与服务器端客户端的连接应该会导致客户端获得EOF。
[编辑-1]
我已经深入研究在这个问题上有点,只是因为我没有在使用了一段时间插座,因为我发现这个问题有意思。我认为,由于它已被其他人指出,唯一的选择是关闭插座,根据Javadocs将自动关闭输入和输出流/
如果有线程未被IO阻塞的机会,但处于等待状态或休眠状态,我认为仍然建议为给定套接字的相应工作线程发出Thread.interrupt();因为不能确定每个线程的状态是否被阻塞。
public static class IOServerWorker implements Runnable{
private Socket socket;
public IOServerWorker(Socket socket){
this.socket = socket;
}
@Override
public void run() {
String line = null;
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((line = reader.readLine())!=null){
System.out.println(line);
}
reader.close();
}catch(IOException e){
//TODO: do cleanup here
//TODO: log | wrap | rethrow exception
}
}
}
当I/O中的工作者被阻塞时,我无法检查这个标志 – 2011-04-11 17:24:39
最佳做法是使用Thread.interrupted()。这是标准的解决方案,可以在ThreadPool中正常工作。 – 2011-04-11 19:04:45
@Andrey Vityuk Thread.interrupted实际上不是很好的做法,因为它重置了中断标志。你可能意味着Thread.interrupt或Thread.isInterrupted。这就是说,正如我在我的回答中所说的,许多IO构造不考虑线程中断,因此(尽管我部分同意你的评论)它不适用于这种情况。 – 2011-04-12 00:30:53