Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given two Java threads, stop one thread when one of them finishes

I'm looking for a clean design/solution for this problem: I have two threads, that may run as long as the user wants to, but eventually stop when the user issues the stop command. However if one of the threads ends abruptly (eg. because of a runtime exception) I want to stop the other thread.

Now both threads execute a Runnable (so when I say 'stop a thread' what I mean is that I call a stop() method on the Runnable instance), what I'm thinking is to avoid using threads (Thread class) and use the CompletionService interface and then submit both Runnables to an instance of this service.

With this I would use the CompletionService's method take(), when this method returns I would stop both Runnables since I know that at least one of them already finished. Now, this works, but if possible I would like to know of a simpler/better solution for my case.

Also, what is a good solution when we have n threads and as soon as one of them finishes to stop execution of all the others ?

Thanks in advance.

like image 201
jplot Avatar asked Dec 16 '22 16:12

jplot


1 Answers

There is no Runnable.stop() method, so that is an obvious non-starter.

Don't use Thread.stop()! It is fundamentally unsafe in the vast majority of cases.

Here are a couple of approaches that should work, if implemented correctly.

  1. You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)

  2. You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes.


I know Runnable doesn't have that method, but my implementation of Runnable that I pass to the threads does have it, and when calling it the runner will finish the run() method (something like Corsika's code, below this answer).

From what I can tell, Corsika's code assumes that there is a stop() method that will do the right thing when called. The real question is how have you do implemented it? Or how do you intend to implement it?

  • If you already have an implementation that works, then you've got a solution to the problem.

  • Otherwise, my answer gives two possible approaches to implementing the "stop now" functionality.

I appreciate your suggestions, but I have a doubt, how does 'regularly check/call' translate into code ?

It entirely depends on the task that the Runnable.run() method performs. It typically entails adding a check / call to certain loops so that the test happens reasonably often ... but not too often. You also want to check only when it would be safe to stop the computation, and that is another thing you must work out for yourself.

like image 115
Stephen C Avatar answered Dec 28 '22 08:12

Stephen C