Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java long running task Thread interrupt vs cancel flag

I have a long running task, something like:

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

The task can be cancelled (a cancel is requested and checkIfCancelRequested() checks the cancel flag). Generally when I write cancellable loops like this, I use a flag to indicate that a cancel has been requested. But, I know I could also use Thread.interrupt and check if the thread has been interrupted. I'm not sure which would be the preferred approach and why, thoughts?

thanks,

Jeff

like image 613
Jeff Storey Avatar asked Dec 16 '09 14:12

Jeff Storey


People also ask

Does thread interrupt terminate a thread?

interrupt() does not interrupt the thread, it continues to run.

Can a running thread be interrupted?

A thread can send an interrupt by invoking interrupt on the Thread object for the thread to be interrupted. This means interruption of a thread is caused by any other thread calling the interrupt() method. void interrupt() - Interrupts the thread.

What happens if thread is interrupted in Java?

In Java, an InterruptedException will be thrown if the thread is currently blocking. If the thread is not blocking, the exception will not be thrown. For . NET languages, a ThreadInterruptedException will be thrown if the thread is currently blocking.

When should we interrupt a thread?

An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.


1 Answers

One problem with using interrupt is that if you do not control all code being executed, you run the risk of the interrupt not working "properly" because of someone else's broken understanding of how to handle interrupts in their library. That is the API invisibly exports an API around its handling of interrupts which you become dependent on.

In your example, suppose doSomeWork was in a 3rd-party JAR and looks like:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

Now you have to handle an AssertionError (or whatever else the library you are using might throw). I've seen experienced developers throw all sorts of nonsense on receiving interrupts! On the other hand, maybe the method looked like this:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

This "improper handling" of interrupt causes your program to loop indefinitely. Again, don't dismiss this as ridiculous; there are a lot of broken interrupt handling mechanisms out there.

At least using your own flag will be completely invisible to any 3rd-party libraries.

like image 163
oxbow_lakes Avatar answered Oct 11 '22 07:10

oxbow_lakes