This question already has an answer here:
这个问题已经有了答案:
- I want my thread to handle interruption, but I can't catch InterruptedException because it is a checked exception 4 answers
- 我希望我的线程处理中断,但是我不能捕捉InterruptedException,因为它是一个检查异常4的答案。
I have the following code:
我有以下代码:
public class Net {
public static void main(String[] args) {
Runnable task = new Runnable() {
@Override
public void run() {
String host = "http://example.example";
try {
URL url = new URL(host);
StringBuilder builder = new StringBuilder();
HttpURLConnection con = (HttpURLConnection) url.openConnection();
try(BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()))) {
String line;
while (null != (line = in.readLine())) builder.append(line);
}
out.println("data: " + builder.length());
con.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(task);
thread.start();
thread.interrupt();
}
}
This "con.getInputStream()" blocks thread, when host is wrong. How to interrupt this code from another thread?
这个“con.getInputStream()”阻塞线程,当主机出错时。如何从另一个线程中断此代码?
4 个解决方案
#1
3
The general rule is to interrupt uninterruptible threads from 'outside', i.e.
一般规则是在“外部”中中断不可中断的线程,即:
- Thread waiting for connection/stream - by closing the connection.
- 线程等待连接/流——通过关闭连接。
- Thread waiting for hang up process to finish - by killing the process.
- 线程等待挂起过程完成-通过杀死进程。
- (not specifically this case) A running long loop - by introducing a boolean variable which is set from outside and checked inside the loop from time to time.
- (不是特别地,这种情况)一个运行长的循环——通过引入一个布尔变量,它从外部设置,并不时地在循环中进行检查。
#2
1
Unfortunately you cannot interrupt the thread which has blocked by some I/O operation(unless you utilize NIO).
you may need to close the stream(by another thread) which reading thread has blocked by.
something like this:
不幸的是,您不能中断被某些I/O操作阻塞的线程(除非您使用NIO)。您可能需要关闭流(通过另一个线程),该线程的读取线程已经被阻塞。是这样的:
public class Foo implements Runnable{
private InputStream stream;
private int timeOut;
....
public void run(){
Thread.sleep(timeOut);
if(<<ensure the victim thread still is stuck>>){
stream.close();//this will throws an exception to the stuck thread.
}
}
....
}
#3
1
Set a timeout value with setReadTimeout
. Catch the SocketTimeoutException
if timeout expires and recover or terminate the program the way you want.
使用setReadTimeout设置超时值。如果超时过期并以您希望的方式恢复或终止程序,则捕获SocketTimeoutException。
#4
0
This "con.getInputStream()" blocks thread, when host is wrong. How to interrupt this code from another thread?
这个“con.getInputStream()”阻塞线程,当主机出错时。如何从另一个线程中断此代码?
This is a FAQ. Interrupting a thread will not cause the readLine(...)
method to be interrupted. To quote from my answer here:
这是一个常见问题。中断一个线程不会使readLine(…)方法被中断。我的回答是:
我希望我的线程处理中断,但是我不能捕捉InterruptedException,因为它是一个受控异常。
It is important to realize that t.interrupt() only sets the interrupted bit in a thread -- it doesn't actually interrupt the thread's processing per se. A thread can be interrupted at any time safely.
重要的是要意识到,.中断()只设置线程中的被中断的部分——它实际上并没有中断线程的处理。线程可以在任何时候安全地中断。
So there is no way you can interrupt the thread if it is blocked in readLine(...)
. You could however change your loop to be something like:
因此,如果线程在readLine(…)中被阻塞,就无法中断线程。但是你可以改变你的循环,比如:
while (!Thread.currentThread().isInterrupted()) {
String line = in.readLine();
if (line == null) {
break;
}
builder.append(line);
}
You can, as others have mentioned, closed the underlying InputStream
which will cause the readLine()
to throw an Exception
.
正如其他人所提到的,您可以关闭底层的InputStream,这将导致readLine()抛出异常。
#1
3
The general rule is to interrupt uninterruptible threads from 'outside', i.e.
一般规则是在“外部”中中断不可中断的线程,即:
- Thread waiting for connection/stream - by closing the connection.
- 线程等待连接/流——通过关闭连接。
- Thread waiting for hang up process to finish - by killing the process.
- 线程等待挂起过程完成-通过杀死进程。
- (not specifically this case) A running long loop - by introducing a boolean variable which is set from outside and checked inside the loop from time to time.
- (不是特别地,这种情况)一个运行长的循环——通过引入一个布尔变量,它从外部设置,并不时地在循环中进行检查。
#2
1
Unfortunately you cannot interrupt the thread which has blocked by some I/O operation(unless you utilize NIO).
you may need to close the stream(by another thread) which reading thread has blocked by.
something like this:
不幸的是,您不能中断被某些I/O操作阻塞的线程(除非您使用NIO)。您可能需要关闭流(通过另一个线程),该线程的读取线程已经被阻塞。是这样的:
public class Foo implements Runnable{
private InputStream stream;
private int timeOut;
....
public void run(){
Thread.sleep(timeOut);
if(<<ensure the victim thread still is stuck>>){
stream.close();//this will throws an exception to the stuck thread.
}
}
....
}
#3
1
Set a timeout value with setReadTimeout
. Catch the SocketTimeoutException
if timeout expires and recover or terminate the program the way you want.
使用setReadTimeout设置超时值。如果超时过期并以您希望的方式恢复或终止程序,则捕获SocketTimeoutException。
#4
0
This "con.getInputStream()" blocks thread, when host is wrong. How to interrupt this code from another thread?
这个“con.getInputStream()”阻塞线程,当主机出错时。如何从另一个线程中断此代码?
This is a FAQ. Interrupting a thread will not cause the readLine(...)
method to be interrupted. To quote from my answer here:
这是一个常见问题。中断一个线程不会使readLine(…)方法被中断。我的回答是:
我希望我的线程处理中断,但是我不能捕捉InterruptedException,因为它是一个受控异常。
It is important to realize that t.interrupt() only sets the interrupted bit in a thread -- it doesn't actually interrupt the thread's processing per se. A thread can be interrupted at any time safely.
重要的是要意识到,.中断()只设置线程中的被中断的部分——它实际上并没有中断线程的处理。线程可以在任何时候安全地中断。
So there is no way you can interrupt the thread if it is blocked in readLine(...)
. You could however change your loop to be something like:
因此,如果线程在readLine(…)中被阻塞,就无法中断线程。但是你可以改变你的循环,比如:
while (!Thread.currentThread().isInterrupted()) {
String line = in.readLine();
if (line == null) {
break;
}
builder.append(line);
}
You can, as others have mentioned, closed the underlying InputStream
which will cause the readLine()
to throw an Exception
.
正如其他人所提到的,您可以关闭底层的InputStream,这将导致readLine()抛出异常。