2

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?

mystdeim
  • 4,802
  • 11
  • 49
  • 77

4 Answers4

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.
Andrey Chaschev
  • 16,160
  • 5
  • 51
  • 68
  • +1 The running long loop can also be terminated by using `while (!Thread.currentThread().isInterrupted) { ... }` – Gray Oct 31 '13 at 18:02
1

Set a timeout value with setReadTimeout. Catch the SocketTimeoutException if timeout expires and recover or terminate the program the way you want.

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:

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.
    }
   }
....
}
0

This "con.getInputStream()" blocks thread, when host is wrong. How to interrupt this code from another thread?

This is a FAQ. Interrupting a thread will not cause the readLine(...) method to be interrupted. To quote from my answer here:

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

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:

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.

Community
  • 1
  • 1
Gray
  • 115,027
  • 24
  • 293
  • 354