5

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:

  • It will do some minor I/O operations
  • It will spend minor time in 3rd party libraries
  • It may create some worker threads for a certain subtask (these threads will not be reused after their task is finished)
  • It will spend most of its time crunching numbers (there are no blocking calls present)

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.

  1. Throw some kind of unchecked exception: this would kill the thread in a quick and easy way, but it reminds me of the 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.
  2. Throw some kind of checked exception: this would kill the thread in a quick and easy way, and alleviates the 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.
  3. Exit the methods with a "best result so far" or empty result. Because of the amount of classes involved, this will be a very hard task. If not enough care is taken, 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.
Community
  • 1
  • 1
DieterDP
  • 4,039
  • 2
  • 29
  • 38
  • You could probably try to streamline (3) in your interrupt handler or handlers; still, might be a good idea considering a combination of that with some sort of RuntimeException. – blgt Sep 05 '13 at 09:09

2 Answers2

1

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.

Tom McIntyre
  • 3,620
  • 2
  • 23
  • 32
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • You only know the safe-to-stop points if all running code is under your control. How would you deal with this if the code is destined for a library? (See point 1 in my question) – DieterDP Sep 05 '13 at 10:11
0

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.

GedankenNebel
  • 2,437
  • 5
  • 29
  • 39
  • This answer tells me how I can create interrupts in my worker thread, but not how I should handle them - which is my actual question. – DieterDP Sep 05 '13 at 10:07