如何中断这个线程?(复制)

时间:2023-02-03 21:03:14

This question already has an answer here:

这个问题已经有了答案:

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(…)方法被中断。我的回答是:

I want my thread to handle interruption, but I can't catch InterruptedException because it is a checked exception

我希望我的线程处理中断,但是我不能捕捉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(…)方法被中断。我的回答是:

I want my thread to handle interruption, but I can't catch InterruptedException because it is a checked exception

我希望我的线程处理中断,但是我不能捕捉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()抛出异常。