Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupting looped threads in Java

I'm trying to understand how threads work in Java and currently investigating how to implement looped threads that can be cancelled. Here's the code:

public static void main(String[] args) throws Exception {
    Thread t = new Thread() {
        @Override
        public void run() {
            System.out.println("THREAD: started");
            try {
                while(!isInterrupted()) {
                    System.out.printf("THREAD: working...\n");
                    Thread.sleep(100);
                }
            } catch(InterruptedException e) {
                // we're interrupted on Thread.sleep(), ok

                // EDIT
                interrupt();

            } finally {
                // we've either finished normally
                // or got an InterruptedException on call to Thread.sleep()
                // or finished because of isInterrupted() flag

                // clean-up and we're done
                System.out.println("THREAD: done");
            }               
        }
    };

    t.start();
    Thread.sleep(500);
    System.out.println("CALLER: asking to stop");
    t.interrupt();
    t.join();
    System.out.println("CALLER: thread finished");
}

The thread I create is indended to be interrupted sooner or later. So, I check isInterrupted() flag to decide whether I need to go on and also catch InterruptedException to handle cases when I'm in a kind of waiting operation (sleep, join, wait).

Things I'd like to clarify are:

  1. Is it fine to use interruption mechanism for this kind of task? (comparing to having volatile boolean shouldStop)
  2. Is this solution correct?
  3. Is it normal that I swallow InterruptedException? I'm not really interested what was the piece of code where someone asked my thread to interrupt.
  4. Are there any shorter ways to solve this problem? (the main point is having 'infinite' loop)

EDIT Added call to interrupt() in catch for InterruptedException.

like image 983
Andrey Agibalov Avatar asked Aug 11 '11 11:08

Andrey Agibalov


People also ask

How do you stop a thread loop in Java?

Using boolean volatile variable We have passed exit variable in the while loop condition. As long as exit variable remains false, the thread keeps on running. We need to set exit variable to true in order to stop the thread. We will use stopThread() method to set the exit variable value to true.

What are interrupting threads in Java?

In Java Threads, if any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked), calling the interrupt() method on the thread, breaks out the sleeping or waiting state throwing InterruptedException.

What happens if thread is interrupted in Java?

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.

What does thread Currentthread () interrupt () do?

Calling Thread. interrupt() is a way to tell the thread to stop what it is doing. If the thread is in a blocking call, the blocking call will throw an InterruptedException, otherwise the interrupted flag of the thread will be set. A Thread or a Runnable that is interruptible should check from time to time Thread.


2 Answers

I am answering no. 3:

Basically the question is: What purpose does an Interrupted exception have? It tells you to stop blocking (e.g. sleeping) and return early.

There are two ways dealing with an InterruptedException:

  • Rethrow it, so the thread remains interrupted
  • set Thread.currentThread.interrupt() again and do your cleanup work. This way you can be sure that another method in your thread starting to sleep will throw again

Simply swallowing an InterruptedException is not a good idea regarding the purpose of such an interrupt which is to finally terminate. But you are only asked to interrupt so you still have time to clean up.

In this case this might be an 'overreaction' of myself, but typically such code is much more complicated and how do you know, that some follow-up-code in this Thread would not call a blocking method again?

EDIT

Otherwise I think what you're doing is fine. For me a bit surprising, though, because I never saw anyone in his own code actually doing it.

And interesting article explaining why can be found here: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html

like image 82
Stefan Schubert-Peters Avatar answered Sep 28 '22 10:09

Stefan Schubert-Peters


  1. Yes, it's fine. You should document how a Thread/Runnable must be stopped. You could add a dedicated stop method on your Runnable implementation that encapsulates the stopping mechanism. Either use interrupt, or use a dedicated boolean value, or both.
  2. Yes, except the good practice is to restore the interrupt status when catching InterruptedException: Thread.currentThread().interrupt();
  3. No, you should restore the interrupt status
  4. None that I'm aware of
like image 33
JB Nizet Avatar answered Sep 28 '22 09:09

JB Nizet