1

I am trying to interrupt thread that is working long. In my example inside run() method appear lots of different method with take quite a lot of time (e.g writing into database). I would like to stop (kill) that thread from another one. I have seen solution like:

while(!Thread.currentThread().isInterrupted()){
    try{
        // do stuff
    }catch(InterruptedException e){
        Thread.currentThread().interrupt(); // propagate interrupt
    }
}

but I've got no while loop inside my code. Can anyone help me to deal with that?


Here's the code:

public void run() //parsingThread
    {
        try {
            for(int index=0; index<tasks.size();)
            { //do sth
                if(Thread.currentThread().isInterrupted()==true)
                {       
                    System.out.println("Parsing ABORTED");
                    Thread.currentThread().interrupt();             
                }               
            }


            for(int index=0; index<1000;index++)
            {   //do sth  
                if(Thread.currentThread().isInterrupted()==true)
                {
                    System.out.println("Parsing ABORTED");
                    Thread.currentThread().interrupt();
                }
            }}
aioobe
  • 413,195
  • 112
  • 811
  • 826
PatLas
  • 179
  • 1
  • 5
  • 16
  • You already seem to know what you need to do. You haven't posted any of your own code so it's difficult to see why you're expecting from us. –  Jun 09 '15 at 08:54
  • If you want to kill a thread from another thread call `thread.interrupt()` where `thread` is the long working thread. Don't use `Thread.currentThread().interrupt();` That's like interrupting yourself. – Codebender Jun 09 '15 at 08:59
  • @AbishekManoharan, OP never suggested interrupting the current thread. I think you misread the question. – aioobe Jun 09 '15 at 09:01
  • In general, it's good practice to put the try/catch around your while loop, instead of inside it. That way, an interrupt will automatically terminate the loop. – VGR Jun 09 '15 at 09:24
  • @Hobo Sapiens I've inserted code in post below. – PatLas Jun 09 '15 at 09:43

2 Answers2

4

If your long-running database calls don't respond to interrupts, then you're basically out of luck, and need to resort to workarounds if you for instance want a responsive user interface.

One way is to run the database methods in a background thread and periodically check for stop-early conditions (such as interruptions) in the main thread. When such condition is discovered, you simply abandon the background thread and ignore any future results from it.

If possible, you could try to split up the long running task into multiple smaller tasks, and check for interrupts in between.

(Some people may point you to Thread.stop, but that method has been deprecated for very good reasons.)

Official documentation (which in part answers the question you posted too):

Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?


Regarding your code.

If //do sth is a long running task, the Thread.currentThread().isInterrupted()==true check is never executed.

I've copied your program and executed it locally, and the "Parsing ABORTED" is being printed for me.

Community
  • 1
  • 1
aioobe
  • 413,195
  • 112
  • 811
  • 826
  • I don’t understand, how adding `index++` ought to make a difference. The loop’s body containing the check is executed, regardless of whether `index++` is present or not. The lack of `index++` makes the loop infinite but doesn’t change the interruption behavior. – Holger Jun 09 '15 at 09:54
  • Hmm. You're absolutely right. I thought it was an unreachability issue, but it's obviously not. Deleting this from my answer. – aioobe Jun 09 '15 at 09:59
0

You are mixing up two entirely different things. Code fragments containing statements like Thread.currentThread().interrupt() are not handling interrupts as said statement is for restoring the interrupt status so that callers may handle it.

Since you want to handle the interrupting, that is not the right thing. If you detect an interruption, you just need a simple statement telling the compiler what to do. So if you want your task to return upon interruption, just use a statement as simple as

if(Thread.currentThread().isInterrupted()) {
    // if you need cleanup, do it here
    return;
}

Generally, don’t copy code from somewhere else whose purpose you don’t understand.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • But as I mention the problem is with detecting isInterrupted() inside loop in code below. – PatLas Jun 09 '15 at 09:44
  • 1
    Add an `else` statement to check whether you even encounter the check. If your code is blocked somewhere else, the check can’t help. If the check is executed but evaluates to `false`, well, then you haven’t interrupted the thread, but maybe some other thread… – Holger Jun 09 '15 at 09:49