简体   繁体   中英

Do I need to check for Thread.isAlive() here?

In a web controller, I have a parent thread that receives requests. Some requests take a long time to process. To prevent clients from timing out, I set up the parent thread to send back a byte every 2 seconds while a child thread is doing the time-consuming part of the operation.

I want to make sure I'm accounting for all possible cases of the child thread dying, but I also don't want to put in any extraneous checks.

Here is the parent thread:

    // This is my runnable class
    ProcessorRunnable runnable = new ProcessorRunnable(settings, Thread.currentThread());
    Thread childThread = new Thread(runnable);
    childThread.start();

    boolean interrupted = false;
    while (!runnable.done) { // <-- Check in question
        outputStream.write(' ');
        outputStream.flush();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // If the runnable is done, then this was an expected interrupt
            // Otherwise, remember the interruption and re-interrupt after processing is done
            // Or with self so that a later expected interrupt won't clear out an earlier unexpected one
            interrupted = interrupted || !runnable.done;
        }
    }
    if (runnable.runtimeException != null) {
        LOG.error("Propagating runtime exception from thread");
        throw runnable.runtimeException;
    }

    // ... Further processing on the results provided by the child thread

And here's ProcessorRunnable:

    private volatile boolean done;
    private volatile Result result;
    private volatile RuntimeException runtimeException;

    // ...

    public void run() {
        done = false;
        try {
            result = myService.timeConsumingOperation(settings);
        } catch (RuntimeException e) {
            runtimeException = e;
        } finally {
            done = true;
            parentThread.interrupt();
        }
    }

My question is, would adding && Thread.isAlive() check in the parent thread's main loop buy me anything? It seems that setting done = true in the finally block should do the trick, but are there some cases where this child thread could die without notifying the parent?

The finally in the child thread will always execute before it finishes. Even if that thread is interrupted or stopped, this happens via an exception that bubbles up the call stack and triggers all finally s. So, done will always be true if the child thread is interrupted.

For background tasks like this you may want to use an ExecutorService instead of raw threads. You can submit a Runnable to an ExecutorService and just call get() on the returned future to block until it is done. If you want to print out spaces while you are waiting, you can use a loop, calling the get() version with a timeout.

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