Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly handle thread interrupts

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.
like image 843
DieterDP Avatar asked Nov 11 '22 22:11

DieterDP


1 Answers

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.

like image 115
Peter Lawrey Avatar answered Nov 14 '22 23:11

Peter Lawrey