Skip to main content

Best way to stop blocking thread

8 replies [Last post]
dpjo
Offline
Joined: 2006-05-10

Hi All,
I am not sure performance forum is right place to put this question...Yet my question is what is the best way to stop a blocking thread(I did google..but could not find good answer so far)? more precisely blocking thread is waiting for a messages on a external messaging system queue, and the system is shutting down.
For non-blocking threads usually I can notify the thread and can make some flag false to come out from while loop inside run() method.
I may want to clean up and close connections before stopping a blocking thread as I can do that in non-blocking threads.

Thanks in advance.
-dpjo

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
fred34
Offline
Joined: 2004-06-19

you say that the blocking thread needs to be stopped since it is stopping the system from shutting down and its actual job is waiting for messages from an external source. This suggests the thread is a service thread rather than a worker thread that the application runs in.

If this is the case, then set the thread as a daemon thread (use Thread.setDaemon(true) before calling its start() method) to tell the JVM that the thread shouldn't be considered critical to the application. Daemon threads do not stop a JVM from closing like other threads will.

sdo
Offline
Joined: 2005-05-23

A daemon thread will allow the JVM to shut down, but the thread won't have a chance to clean up after itself, which is the goal here.

On the other hand, you can never be 100% assured that the JVM (or the entire machine) won't crash, in which case the threads won't have a chance to clean up after themselves anyway, so you need to be prepared for that possibility anyway.

That said, another solution is to call Thread.interrupt() to interrupt the blocking thread, which can catch the InterruptedException or InterruptedIOException and clean up.

dpjo
Offline
Joined: 2006-05-10

Setting daemon did not help. I just want to stop blocking threads, dont want to exit from program.
If I am not wrong interrupt/stop/join/(any other method) does not have any effect on a thread which is blocked unless blocking device/program is “interruptible”.
(I read it somewhere… I may be completely wrong :-) .
I will put my problem once more to make myself clear:
I have a stop button in a gui, when clicked should stop this blocking thread.
I find no way to kill this thread unless of course I exit from the program. Someone
has suggested use available() kind of method on the target system to check periodically, which is not available in my case.

Thanks very much for your reply and for your patient.
-dpjo

fred34
Offline
Joined: 2004-06-19

Calling the interrupt method on a thread won't do anything except set the thread's interrupt flag unless as stated before the thread is blocked in a method that responds to being interrupted, such as Thread.sleep() or Thread.wait(). Not all of the I/O classes blocking methods will respond to being interrupted.

It would help us if we knew what your thread was blocking on, i.e. is it blocking on read() method on an InputStream or some socket reading or in NIO code or something, or is it blocking in your own code that takes a long time to complete. You mention it receives messages from an external source which leans towards being blocked on I/O code.

If this is the case and the particular piece of code is not responding to interrupt calls, then another approach is to try setting a timeout on the blocking method. In socket I/O this is particularly easy, since you can use Socket.setSOTimeout() (or something similar to that) and after the timeout, check the interrupt status on the thread then either clean up and exit or loop back into the I/O code.

dpjo
Offline
Joined: 2006-05-10

My call is blocking on third party API something like below:
while(flag){
try{
Message m=queue.receiveMsg();
//I can reach here only when message comes
//in the queue. Otherwise I will wait forever.
...
}catch(...
}
Obviously I cant alter the way this method behaves. May be I will need to look for some other approach.
Thanks for your help.

briand
Offline
Joined: 2005-07-11

Can you queue a special message to that queue -
one that essentially tells the receiver to exit
the thread (or whatever you plan to do).

sdo
Offline
Joined: 2005-05-23

I'm not sure why I can't remember that Windows OSes can't deal with interrupt properly. But they can't...on other platforms, interrupt should properly interrupt the pending I/O underneath the message call. So if the platform in question in UNIX-based, then using interrupt would still work -- assuming that the third-party API exposes the underlying I/O stream. [It's possible, I suppose, that the third-party API could catch the IOException and retry the call, which also wouldn't help.]

If the API exposes the I/O stream and the application needs to run on Windows, a second alternative is to close the I/O stream. You can also combine the approaches and set up a interrupt watcher class that closes the underlying stream -- check out the examples from Chapter 12 of Java Threads at www.oreilly.com (examples free online).

If the stream isn't exposed, then nothing along these lines will help, and an application-level suggestion like Brian's will be required (which might be cleaner anyway).

dpjo
Offline
Joined: 2006-05-10

With little more investigation I found that API is eating exception inside the getMessage() call. Yet Brian's solution works for me with little tweak.
Thank you all for your pointers and expert advice.
-dpjo