Reputation: 4347
I am working on an application that at some point starts a worker thread. This thread's behaviour will vary greatly depending on the parameters used to start it, but the following list of properties apply:
Due to the possible long duration (5 minutes up to several hours, depending on the input), we want to be able to abort the calculation. If we choose to abort it, we no longer care about the output, and the thread is in fact wasting valuable resources as long as it keeps running. Since the code is under our control, the advised way is to use interrupts to indicate an abort.
While most examples on the web deal with a worker thread that is looping over some method, this is not the case for me (similar question here). There are also very few blocking calls in this work thread, in which case this article advises to manually check the interrupt flag. My question is: How to deal with this interrupt?
I see several options, but can't decide which is the most "clean" approach. Despite my practical example, I'm mainly interested in the "best practice" on how to deal with this.
ThreadDeath
approach used by the deprecated Thread#stop()
method, with all its related problems. I can see this approach being acceptable in owned code (due to the known logic flow), but not in library code.ThreadDeath
-like problems by enforcing programmers to deal with this event. However, it places a big burden on the code, requiring the exception to be mentioned everywhere. There is a reason not everything throws an InterruptedException
.NullPointerExceptions
might arise from empty results, leading to the same problems as point 1. Finding these causes would be next to impossible in large code bases.Upvotes: 5
Views: 302
Reputation: 533500
I suggest you check Thread.currentThread().isInterrupted() periodically at points you knwo it is safe to stop and stop if it is set.
You could do this in a method which checks this flag and throws a custom unchecked exception or error.
Upvotes: 1
Reputation: 2587
What about a use of ExecutorService to execute the Runnable? Checkout the methods wherein you can specify the timeout. E.g.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Here Task of course implements Runnable.
Upvotes: 0