Java wait for runnable to finish

I have a class that will start a Runnable with an infinite loop. At some point, I want to shut down the program, and I want to do it in a clean way (e.g. ensure that at the end of the execution the thread will flush some buffer to output file and such). How can I do it?

Note: in the comments I wrote // Version 1 and // Version 2. That is because I tried both version and none of them worked, I keep getting an InterruptedException.

Main Class:

public class MainClass {

    private static Thread myThread;
    private static MyRunnable myRunnable;
    private static Logger logger;

    public static void main( String[] args ) {
        ...
        myRunnable = new MyRunnable(logger);
        myThread = new Thread(myRunnable);
        myThread.start();
        ...
    }

    private static void shutDown() {
        logger.debug("Shut down everything.");
        if(myRunnable != null){
            myRunnable.shutdown();
            try {
                myThread.join();
                logger.debug("Runnable Stopped");
            } catch (InterruptedException e) { // Always failing here
                e.printStackTrace();
            }
        }
        // Now stop logger and other things
        logger.debug("Shutdown other stuff");
        ...
        logger.debug("Shutdown logger");
        Configurator.shutdown((LoggerContext)LogManager.getContext());
        System.out.println("Done");
    }
}

Runnable class:

public class MyRunnable implements Runnable {

    private AtomicBoolean stop = new AtomicBoolean(false); // Version 1

    public boolean isStopped() { 
        return stop.get(); // Version 1
        return Thread.currentThread().isInterrupted(); // Version 2
    }

    public void shutdown() {
        logger.debug("Stopping my runnable");
        stop.set(true); // Version 1
        Thread.currentThread().interrupt(); // Version 2
    }

    @Override
    public void run() {
        try{
            while(!isStopped()) {
                // Do things
            }
            logger.debug("Exiting from infinite loop");
        } catch(Exception e){
            logger.error("Exception! " + e.getMessage());
        } finally {
            logger.debug("Entering in finally part");
            // Flush buffer, commit to database, ... close stuff
        }
    }
}

But the output of the shutDown function is always the same:

Shut down everything.
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Thread.join(Thread.java:1260)
    at java.lang.Thread.join(Thread.java:1334)
    at com.my.packageName.MainClass.shutDown(MainClass.java:374)
Shutdown other stuff
Shutdown logger
Done

If I remove the join() function, the Exception goes away, but the output is still the same.


EDIT: I just noticed that if I comment the line myRunnable.shutdown(); and I go on with the myThread.join(); line, I still get the exception, even if I am not stopping that thread. Why is that? Is it because the Tread and the Runnable are two separate things? If it is so, then how can I stop the Runnable and wait for its completion?

Answer

In “version 2”, you are interrupting the thread that is calling stopParser(), not the thread that is executing run(). Instead of calling Thread.currentThread().interrupt(), use myThread.interrupt().

I don’t know why you’d get an InterruptedException in “version 1”; you must be calling Thread.currentThread().interrupt() somewhere else. You should only do that when you have detected that the current thread has been interrupted by another thread but you can’t terminate the thread immediately.

Leave a Reply

Your email address will not be published. Required fields are marked *