Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find and stop all currently running threads?

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(); 
}
like image 917
Li' Avatar asked Mar 25 '13 20:03

Li'


People also ask

How do I stop all running threads?

Whenever we want to stop a thread from running state by calling stop() method of Thread class in Java. This method stops the execution of a running thread and removes it from the waiting threads pool and garbage collected. A thread will also move to the dead state automatically when it reaches the end of its method.

How do I destroy all threads?

Modern ways to suspend/stop a thread are by using a boolean flag and Thread. interrupt() method. Using a boolean flag: We can define a boolean variable which is used for stopping/killing threads say 'exit'. Whenever we want to stop a thread, the 'exit' variable will be set to true.

How do I get the current running thread?

A thread can be created by implementing the Runnable interface and overriding the run() method. The current thread is the currently executing thread object in Java. The method currentThread() of the Thread class can be used to obtain the current thread. This method requires no parameters.

How do you check if a thread is still running?

Use Thread. currentThread(). isAlive() to see if the thread is alive[output should be true] which means thread is still running the code inside the run() method or use Thread.


2 Answers

This is a dangerous idea. The Javadoc for Thread.stop() explains:

This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.

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:

public abstract class StoppableRunnable implements Runnable {
    private volatile boolean stopWork;
    private boolean done;

    public final void run() {
        setup();
        while(!stopWork && !done) {
            doUnitOfWork();
        }
        cleanup();
    }

    /**
     * Safely instructs this thread to stop working,
     * letting it finish it's current unit of work,
     * then doing any necessary cleanup and terminating
     * the thread.  Notice that this does not guarentee
     * the thread will stop, as doUnitOfWork() could
     * block if not properly implemented.
     */
    public void stop() {
        stopWork = true;
    }

    protected void done() {
        done = true;
    }

    protected void setup() { }
    protected void cleanup() { }

    /**
     * Does as small a unit of work as can be defined
     * for this thread.  Once there is no more work to
     * be done, done() should be called.
     */
    protected abstract void doUnitOfWork();
}

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 use Thread.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 using kill 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 call Thread.interrupt(), the thread could start it's proper interrupt-handling behavior, then midway through that, your call to Thread.stop() fires, violently killing the thread and potentially breaking your JVM. Calls to Thread.interrupt() provide no guarantee as to when or how the thread will respond to that interrupt, which is why I prefer the explicit behavior in StoppableRunnable. Needless to say, if you're ever going to call Thread.stop() there's little to be gained by calling Thread.interrupt() first. I don't recommend it, but you might as well just call Thread.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.

like image 171
dimo414 Avatar answered Oct 27 '22 07:10

dimo414


I used this code:

package com.xxx;

import com.xxx.tools.messageLog;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Mostafa Nazari
 */
public class ProcessAgent extends Thread{

    public ProcessAgent() {
        super("Process-Agent");
    }


    @Override
    public void run() {
        try {
            com.xxx.Process.agent.Main.main(new String[]{});
        } catch (Exception ex) {
            if (ex instanceof InterruptedException) {
                messageLog.stdwar("Process Agent Stopped");
            }else {
                messageLog.stderr("FATAL Error: "+ex.getMessage());
                Logger.getLogger(ProcessAgent.class.getName()).log(Level.SEVERE, null, ex);            
            }
        }    
    }

    public void terminate() {
        if (super.isAlive()) {
            ThreadGroup group = super.getThreadGroup();
            while (group != null) {
                group .interrupt();
                group = super.getThreadGroup();
            }
            super.interrupt();
        }
    }

    public String getStatus() {
        if (super.isAlive()) {
            return "running";
        } else {
            if (super.isInterrupted()) 
                return "stopping";
            else
                return "stopped";
        }
    }

}

hope it is useful for this issue

like image 30
Mostafa Nazari Avatar answered Oct 27 '22 08:10

Mostafa Nazari