简体   繁体   中英

What is the preferred way to use interrupt a Java Runnable and run clean up?

General question about design here. I have a few threads that need to stay running in the background, basically some database upload/failure handling tasks. The all have the following flow pattern:

public class Worker implements Runnable {
    private AtomicBoolean isAlive = new AtomicBoolean(true);
    ....
    public void run() {
        while (isAlive.get()) {

            // do some work here, slightly heavy

            if (Thread.interrupted()) {
                // checking Thread.interrupted() as the code above
                // can take a while and interrupt may happen before 
                // it gets here.
                isAlive.setBoolean(false);
                break; // to exit faster
            }

            try { Thread.sleep(sleepTime); } 
            catch (InterruptedException e) {
                isAlive.setBoolean(false);
                break; // to exit faster
            }
        }

        cleanUp(); // e.g. close db connections etc
     }
}

Now I would like to be able to interrupt the threads so it can break out of the while loop gracefully and run the cleanUp() method.

There are many ways to do this, to list a few:

  1. Kick the Runnables off in Threads , then use the interrupt() method:

     List<Thread> threadList =... for (int i < 0; i < threadCount; i++) { Thread t = new Thread(new Worker()); threadList.add(t); t.start() } // later for (Thread t : threadList) { t.interrupt(); } 
  2. ThreadPoolExecutor, then use shutdownNow() :

     ThreadPoolExecutor executor = new ....; executor.execute(new Worker()); // some lines else later executor.shutdownNow(); // shutdown() doesn't interrupt? 

What is the way to handle this type of workflow and why? All ideas welcome.

Over all, I personally think setting isAlive to false is the cleanest. According to my knowledge, interrupt() is native code, which is a reason itself to stay away from.

Don't forget to set the boolean to volatile .

I think both are acceptable approaches. If you have a lot of threads, I'd go with the threadpool approach for the easier management. If you just have one (maybe two) threads, I would interrupt them individually.

As MouseEvent stated, it would be cleaner to not use the interrupt and use that isAlive variable (which seems to be pointless in your implementation). This, however, implies that you need to close or shutdown each of the instances (still a good approach)

Also, I would surround the entire method in a try-catch-finally statement where you catch the interruption and have the cleanup in the finally clause.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM