java 使用套接字 I/O 阻塞操作中断/停止线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12315149/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Interrupt/stop thread with socket I/O blocking operation
提问by amp
At some point of my server application I want to stop some threads that are performing I/O blocking operations.
在我的服务器应用程序的某个时刻,我想停止一些正在执行 I/O 阻塞操作的线程。
For instance, one of them have the following run()
method:
例如,其中之一具有以下run()
方法:
public void run() {
System.out.println("GWsocket thread running");
int len;
byte [] buffer = new byte[1500];
try {
this.in = new DataInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream());
running = true;
while (running){
len = in.read (buffer);
if (len < 0)
running = false;
else
parsepacket (buffer, len);
}
}catch (IOException ex) {
System.out.println("GWsocket catch IOException: "+ex);
}finally{
try {
System.out.println("Closing GWsocket");
fireSocketClosure();
in.close();
out.close();
socket.close();
}catch (IOException ex) {
System.out.println("GWsocket finally IOException: "+ex);
}
}
}
If I Want to stop a thread running this code, what should I do?
如果我想停止运行此代码的线程,我该怎么办?
Herethey show how to do (How do I stop a thread that waits for long periods (e.g., for input)?), but I don't understand what they mean with:
在这里,他们展示了如何做(如何停止等待长时间(例如,输入)的线程?),但我不明白它们的含义:
For this technique to work, it's critical that any method that catches an interrupt exception and is not prepared to deal with it immediately reasserts the exception. We say reasserts rather than rethrows, because it is not always possible to rethrow the exception. If the method that catches the InterruptedException is not declared to throw this (checked) exception, then it should "reinterrupt itself" with the following incantation: Thread.currentThread().interrupt();
要使该技术发挥作用,任何捕获中断异常但未准备好立即处理该异常的方法都必须立即重新声明异常,这一点至关重要。我们说重新断言而不是重新抛出,因为重新抛出异常并不总是可能的。如果未声明捕获 InterruptedException 的方法抛出此(已检查的)异常,则应使用以下咒语“重新中断自身”: Thread.currentThread().interrupt();
Can anyone give me some hints? Some code examples would be very appreciated.
谁能给我一些提示?一些代码示例将不胜感激。
回答by Peter Lawrey
You can add a method like
您可以添加一个方法,如
public void close() throws IOException {
this.socket.close();
}
and any blocking IO operations will throw a SocketException.
并且任何阻塞的 IO 操作都会抛出一个 SocketException。
You might like to set a flag like closed
which you can check if an exception thrown was to be expected or not.
您可能希望设置一个标志closed
,以便您可以检查是否会引发异常。
BTW: You cannot be sure that you will get discrete packets on a read. It is far better to read what you need and use BufferedInputStream for efficiency. Only read blocks if you don't need to parse the contents e.g. copying from a socket to a file.
顺便说一句:你不能确定你会在读取时得到离散的数据包。阅读您需要的内容并使用 BufferedInputStream 以提高效率要好得多。如果您不需要解析内容,例如从套接字复制到文件,则仅读取块。
e.g. your read could get just one byte or get the end of one packet and the start of another.
例如,您的读取可能仅获得一个字节或获得一个数据包的结尾和另一个数据包的开始。
回答by Denys Séguret
A solution, described by Peter Lawrey and also seen hereis to close the socket.
由 Peter Lawrey 描述并在此处看到的解决方案是关闭套接字。
With nio, You could also use a SocketChannelwhich is interruptibleand would allow the application of the standard interrupt model of Java.
使用 nio,您还可以使用可中断的SocketChannel,并允许应用Java的标准中断模型。
A call to the interruptmethod of your Thread object would throw an InterruptedException which would stop even your blocking IO operation.
调用Thread 对象的中断方法会抛出一个 InterruptedException ,它甚至会停止阻塞 IO 操作。