views:

85

answers:

3

I am trying to read input from a socket line by line in multiple threads. How can I interrupt readLine() so that I can gracefully stop the thread that it's blocking?

A: 

I think that you might have to use something other than readLine(). You could use read() and at every loop iteration check to see if the thread was interrupted and break out of the loop if it was.

BufferedReader reader = //...
int c;
while ((c = reader.read()) != -1){
  if (Thread.isInterrupted()){
    break;
  }
  if (c == '\n'){
    //newline
  }
  //...
}
Michael Angstadt
Might this cause a sort of busy-waiting situation? Or, if read() blocks as well and does not respond to Thread.interrupt(), then it might have the same problem as I originally had.
Jack
Yes, if `read()` blocks, then you're still stuck with the same problem. You might be able to just close the `BufferedReader` instance from another thread. If this works, it might cause the `read()`/`readLine()` methods to return. It would probably throw an IOException too.
Michael Angstadt
+1  A: 

you can design a Timer class around the read() block.

you need to set a timeout for your timer.

on timeout just interrupt your thread.

mohammad shamsi
+1  A: 

Close the socket on the interrupting thread. This will cause an exception to be thrown on the interrupted thread.

For more information on this and other concurrency issues, I highly recommend Brian Goetz's book "Java Concurrency in Practice".

Steve Emmerson
Out of curiosity, is it possible to achieve the same effect by closing the BufferedReader itself?
Jack
@Jack: yes, closing BufferedReader will close underlying SocketInputStream and the Socket itself.
tulskiy
(`SocketInputStream` is an internal implementation class of some (I believe) but not necessarily all implementations.)
Tom Hawtin - tackline