I have an multiple-threaded java project and I want to add a method stop() to stop all the running threads. The problem is that this project is developed by someone else, and I am not familiar with how it implements multiple threads.
What I know is that once the project get started, many threads are invoked and they run forever. Is there a way to find all running threads and stop them? I have searched a lot, and found how to get a list of running threads:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
What to do next to stop all the running threads?
The reason why I want to stop these threads is that I need to deploy this project to OSGi container as a bundle. Once the bundle is started, multiple threads run forever. So I need to implement a destroy() method to stop all threads to control the bundle lifecycle.
How about
for (Thread t : Thread.getAllStackTraces().keySet())
{ if (t.getState()==Thread.State.RUNNABLE)
t.interrupt();
}
for (Thread t : Thread.getAllStackTraces().keySet())
{ if (t.getState()==Thread.State.RUNNABLE)
t.stop();
}
I used this code:
hope it is useful for this issue
This is a dangerous idea. The Javadoc for
Thread.stop()
explains:Fundamentally, threads need to be built and designed to safely terminate, it is not possible to safely kill arbitrary threads. A fairly standard pattern is implemented like so:
You implied you aren't the author of these threads, which suggest they may not be safely stoppable. In such a case, you can call
Thread.interrupt()
to instruct the thread to stop what it's doing (instead of the pattern described above, you could useThread.interrupt()
to similar effect) however similarly, if the thread's designer hasn't written it to handle interrupts, this may not do anything or cause inconsistent states or other errors.Ultimately,
Thread.stop()
is what you want if you just want to "[Force] the thread to stop executing" and can't modify the thread's implementation; however like usingkill
in Unix, this is a dangerous proposition, and you should essentially consider your JVM to be in an unstable and irreparable state after terminating a thread in this way, and attempt to exit the program as quickly as possible thereafter.Regarding your suggestion of interrupting then stopping:
There's still a lot of problems here, in particular, interrupting does not guarantee the thread will interrupt immediately (it works similarly, though less explicitly, to my
StoppableRunnable
above) and instead sets a flag that the thread should interrupt when possible. This means you could callThread.interrupt()
, the thread could start it's proper interrupt-handling behavior, then midway through that, your call toThread.stop()
fires, violently killing the thread and potentially breaking your JVM. Calls toThread.interrupt()
provide no guarantee as to when or how the thread will respond to that interrupt, which is why I prefer the explicit behavior inStoppableRunnable
. Needless to say, if you're ever going to callThread.stop()
there's little to be gained by callingThread.interrupt()
first. I don't recommend it, but you might as well just callThread.stop()
in the first place.Additionally, recognize that the code running your loop is itself in a thread - meaning your loop could very well kill itself first, leaving all other threads running.
Instead of creating normal
Thread
, use advanced concurrent API like ExecutorService or ThreadPoolExecutorYou can have a look at different APIs in this post:
Java's Fork/Join vs ExecutorService - when to use which?
Refer to below SE questions for forced shut down of ExecutorService:
How to forcefully shutdown java ExecutorService