user2889419
user2889419

Reputation:

How to interupt a thread blocked by some socket IO operation without closing it

I am really wondered how to interrupt a thread which is blocked by some I/O operation? The I/O is through a socket, and I do not want to close() the socket.

I tried using Thread.interrupt() to interrupt the thread, but without success.

Thread blocked by IO operation:

void run(){
    byte[] data=new byte[1024];
    in.read(data);//blocked!
}

Thread to interrupt the blocked thread (did not work):

void run(){
    blockedThread.interrupt();//no success!
}

Upvotes: 3

Views: 1313

Answers (7)

user207421
user207421

Reputation: 310957

Set a shortish read timeout on the socket and loop while you get SocketTimeoutException, checking Thread.isInterrupted() each time. Use Thread.interrupt() to interrupt the thread.

Upvotes: 3

Jans
Jans

Reputation: 11250

I/O like the operations that are waiting for any monitor are not interruptible that is the reason that the InterruptedException rutine is not needed by those cases, but according to Java 7 Documentation the I/O classes that belong to nio package can respond to any attempt to be interruted throwing one of the stream Interruption exception one of this is ClosedByInterruptionException and it parent class AsynchronousCloseException.

But in case that you want to close the excution thead, instead of closing the stream, you could consider make use of FutureTask that provide the way to cancel.

Upvotes: 1

Ortwin Angermeier
Ortwin Angermeier

Reputation: 6193

Take a look at this blog post, especially Solution 4 – NIO with Buffering.

In short: For regular files you have to use NIO, use a Channel that extends AbstractInterruptableChannel, eg. FileChannel.

When using sockets use Socket#close() to interrupt/close.

According to the javadocs:

Any thread currently blocked in an I/O operation upon this socket will throw a SocketException.

BUT:

There is another way around the problem: use asynchronous IO with NIO, take a look at here. The problem with asynchronous IO is, that it is really complex to handle(compared to blocking IO), since you will not relay on streams anymore, but buffers.

Upvotes: 1

dcernahoschi
dcernahoschi

Reputation: 15240

If you absolutely can't/don't want to close the socket using the normal java Socket class, you can use a java.nio.SocketChannel to work with the socket.

SocketChannel implements InterruptibleChannel which can be closed by interrupting the thread that waits on I/O on the socket. In this case the blocked read will throw a ClosedByInterruptException

Upvotes: 3

Rahul Tripathi
Rahul Tripathi

Reputation: 172458

You can add a method like this as any blocking IO operation will throw an IOException:-

public void close() throws IOException {
    this.socket.close();
}

From the javadoc:-

Closes this socket. Any thread currently blocked in accept() will throw a SocketException.

Upvotes: 2

nanofarad
nanofarad

Reputation: 41281

Note how there is no InterruptedException declared to be thrown:

read

public int read(byte[] b)
         throws IOException

Reads some number of bytes from the input stream and stores them into the buffer array b. The number of bytes actually read is returned as an integer. This method blocks until input data is available, end of file is detected, or an exception is thrown.

Some read methods will respond to an external interrupt via Thread#interrupt(), either closing the stream or throwing an exception.

You can't otherwise stop this thread without somehow closing or feeding the stream from another thread, or by killing the thread with Thread#stop(). This last method is only a last resort and shouldn't be used for assorted reasons.

Upvotes: 1

jtahlborn
jtahlborn

Reputation: 53694

Unfortunately, the sun java impl on most platforms does not handle io interruption via thread interrupt (i believe you can get this with some of the nio stuff, unsure). however, i believe if the thread is blocked reading from a socket, and you have a handle to that socket, you can asynchronously close the socket from another thread (which will interrupt the blocked thread).

Upvotes: 1

Related Questions