Question

In my application each request has its own thread. I use JMX/JConsole to monitor them, measure the elapsed time. If a a request needs too much time I'd like to stop it by interrupting the underlying thread. In a method that I call from JConsole I iterate over the list of threads and call interrupt() on the right instance.
However simply calling the interrupt() method on the thread instance only sets a flag, so I need to throw an InterruptedException, too. But this InterruptedException will apply to currentThread instead of the thread I actually want to stop. Any hint how to shut down the flagged thread?

    while (iterator.hasNext()) {
                    RequestHolder rh = iterator.next();
                    if (rh.getThread().getId() == threadId) {
                        rh.getThread().interrupt();
                        if(rh.getThread().isInterrupted()){

                            throw new InterruptedException();
                        }
                    }
                }
Was it helpful?

Solution

But this InterruptedException will apply to currentThread instead of the thread I actually want to stop.

You can check the interruption status of any thread using isInterrupted. However, it is not recommended as a black-boxed approach if you don't know how and when the interruption gets consumed.

Any hint how to shut down the flagged thread?

You cannot cleanly shutdown a thread from another thread.

But it is very simple. In the threads that are running, check for Interruption regularly, such as in loop catch InterruptedException for blocking functions. When you see the interruption in the thread, make it terminate itself. In a sense, the Threads implement their own termination policy.

OTHER TIPS

There is no benefit to throwing InterruptedException. Your if (rh.getThread().isInterrupted()) block can be removed.

Each thread must monitor its own interrupted state, and must exit gracefully when it sees that it has been interrupted.

Usually the code looks something like this:

try {
    InputStream in = socket.getInputStream();
    while (in.read(buffer) >= 0) {
        if (Thread.interrupted()) {
            logger.log(Level.FINE, "Interrupted; exiting");
            break;
        }

        // Process request buffer here
    }
} catch (InterruptedIOException e) {
    logger.log(Level.FINE, "Interrupted; exiting", e);
}

If you are using Channels, you'll want to catch ClosedByInterruptException as well.

you can pass the reference of the thread to be terminated in the constructor of the thread responsible for performing the termination of the first one. Then you can destroy the thread using its reference from another thread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top