How to Abort a Thread in a Fast and Clean Way in Java

How to abort a thread in a fast and clean way in java?

Try interrupt() as some have said to see if it makes any difference to your thread. If not, try destroying or closing a resource that will make the thread stop. That has a chance of being a little better than trying to throw Thread.stop() at it.

If performance is tolerable, you might view each 3D update as a discrete non-interruptible event and just let it run through to conclusion, checking afterward if there's a new latest update to perform. This might make the GUI a little choppy to users, as they would be able to make five changes, then see the graphical results from how things were five changes ago, then see the result of their latest change. But depending on how long this process is, it might be tolerable, and it would avoid having to kill the thread. Design might look like this:

boolean stopFlag = false;
Object[] latestArgs = null;

public void run() {
while (!stopFlag) {
if (latestArgs != null) {
Object[] args = latestArgs;
latestArgs = null;
perform3dUpdate(args);
} else {
Thread.sleep(500);
}
}
}

public void endThread() {
stopFlag = true;
}

public void updateSettings(Object[] args) {
latestArgs = args;
}

How do you kill a Thread in Java?

See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.

The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.

killing a running thread in java?

You can ask the thread to interrupt, by calling Thread.interrupt()

Note that a few other methods with similar semantics exist - stop() and destroy() - but they are deprecated, because they are unsafe. Don't be tempted to use them.

How a thread should close itself in Java?

If you want to terminate the thread, then just returning is fine. You do NOT need to call Thread.currentThread().interrupt() (it will not do anything bad though. It's just that you don't need to.) This is because interrupt() is basically used to notify the owner of the thread (well, not 100% accurate, but sort of). Because you are the owner of the thread, and you decided to terminate the thread, there is no one to notify, so you don't need to call it.

By the way, why in the first case we
need to use currentThread? Is Thread
does not refer to the current thread?

Yes, it doesn't. I guess it can be confusing because e.g. Thread.sleep() affects the current thread, but Thread.sleep() is a static method.

If you are NOT the owner of the thread (e.g. if you have not extended Thread and coded a Runnable etc.) you should do

Thread.currentThread().interrupt();
return;

This way, whatever code that called your runnable will know the thread is interrupted = (normally) should stop whatever it is doing and terminate. As I said earlier, it is just a mechanism of communication though. The owner might simply ignore the interrupted status and do nothing.. but if you do set the interrupted status, somebody might thank you for that in the future.

For the same reason, you should never do

Catch(InterruptedException ie){
//ignore
}

Because if you do, you are stopping the message there. Instead one should do

Catch(InterruptedException ie){
Thread.currentThread().interrupt();//preserve the message
return;//Stop doing whatever I am doing and terminate
}

Stopping a non-looping Java thread

Find out what takes a while, and cancel it. If the thing that takes the most time are the rs.next() loops, you can do:

while(rs.next()){
if (myVolatileBooleanSaysToStop) {
return; // or whatever
}
//do stuff
}

If the thing that takes a while are the statements, and your JDBC driver/server support Statement.cancel, then you can publish your Statement to a second thread which is responsible for calling Statement.cancel as appropriate. I'm not sure, but I think that'll result in a SQLException from the driver, which you can then somehow identify as having come from the cancellation, and handle accordingly.

Also, you should consider refactoring a bit. You have three chunks of "run a query, iterate over its results" that could be factored into a method (which would then take care of closing the statement, etc).

Stopping a thread in an executor service

The only proper way to do this is to cancel the Future corresponding to your task and in your task, you should check regularly if the thread has been interrupted or not.

Something like that:

public class Task implements Callable<Void> {
@Override
public Void call() throws InterruptedException {
while(true) {
// Check regularly in your code if the thread has been
// interrupted and if so throws an exception to stop
// the task immediately
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Thread interrupted");
}
}
}
}

Then your main code would be:

ExecutorService service = Executors.newCachedThreadPool();
// My task
Task task = new Task();
// Submit the task and get the corresponding future
Future<?> future = service.submit(task);
...
// Cancel the task which will interrupt the thread that was executing the
// task if any
future.cancel(true);


Related Topics



Leave a reply



Submit