3

I am writing a program where i invoke multiple threads from my main function. There is a For loop which starts threads in a loop. I want to implement a functionality where if some exception occurs in one thread then it should stop all the currently running/submitted threads, or the threads in waiting state. And also no more further threads should be submitted from the loop.

P.S. I am maintaining a Map which keeps record of all threads Map <threadName, Thread> And i am not using executor service.

How to kill or stop all threads and prevent further threads from being submitted after some exception occurs in any one thread.

chumak
  • 117
  • 1
  • 9
  • What's your question exactly? – shmosel Dec 21 '16 at 06:48
  • 3
    see https://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java?rq=1 you probably should use some ExecutorService –  Dec 21 '16 at 06:52
  • @sh How to stop all threads all the threads (currently running, or waiting to be submitted) if some exception occurs in any thread. – chumak Dec 21 '16 at 06:52
  • 1
    @RC is right. See https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html You will find some shutdown methods there. – Shubham Chaurasia Dec 21 '16 at 07:09

4 Answers4

2

Note that there is no "built in" functionality to stop a thread in java - some methods do exist but all are deprecated since they might cause trouble if the running code is not cooperative. So your code must implement some method to exit the run()-method based on some flag and this must be set from outside the thread. If your threads are using wait() a lot a call to interrupt() might come in handy.

piet.t
  • 11,718
  • 21
  • 43
  • 52
2

You can't forcefully stop a thread in Java.

Yes, there are methods like Thread.stop() and related, but they've been deprecated for years for good reason.

Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock all the monitors that it has locked. (The monitors are unlocked as the ThreadDeath exception propagates up the stack.) If any of the objects previously protected by these monitors were in an inconsistent state, other threads may now view these objects in an inconsistent state. Such objects are said to be damaged. When threads operate on damaged objects, arbitrary behavior can result. This behavior may be subtle and difficult to detect, or it may be pronounced. Unlike other unchecked exceptions, ThreadDeath kills threads silently; thus, the user has no warning that his program may be corrupted. The corruption can manifest itself at any time after the actual damage occurs, even hours or days in the future.

Because of the above, you shouldn't use those methods, nor rely on them working (many APIs with thread-heavy methods will happily ignore any calls to stop() and interrupt()).

Once we got that out of the way, you can still implement logic for your threads to terminate ASAP when you ask them to, in an elegant manner.

You need to do two things:

1.- Check for Thread.interrupted() inside your run() method. Something like this:

@Override
public synchronized void run() {
    while (yourFinishCondition && !Thread.interrupted()) {
        // do stuff until you finish, or until the thread is interrupted from the outside
    }
}

2.- Invoke interrupt() on every thread from your main method to signal them for termination when you need to, like this:

Thread.UncaughtExceptionHandler h = (thread, exception) -> {
    thread0.interrupt();
    thread1.interrupt();
    thread2.interrupt();
};

A little PoC:

public class Main {

    static class MyThread extends Thread {
        public MyThread(String s) {
            super(s);
        }
        @Override
        public synchronized void run() {
            while(!Thread.interrupted()) {
                if (new Random().nextInt(1000000) == 7) {
                    throw new RuntimeException(Thread.currentThread().getName()+" oops!");
                }
            }
            System.out.println(Thread.currentThread().getName()+" interrupted");
        }
    }

    public static void main(String[] args) {
        final MyThread thread0 = new MyThread("thread0");
        final MyThread thread1 = new MyThread("thread1");
        final MyThread thread2 = new MyThread("thread2");

        Thread.UncaughtExceptionHandler h = (thread, exception) -> {
            System.out.println(exception.getMessage());
            thread0.interrupt();
            thread1.interrupt();
            thread2.interrupt();
        };
        thread0.setUncaughtExceptionHandler(h);
        thread1.setUncaughtExceptionHandler(h);
        thread2.setUncaughtExceptionHandler(h);

        thread0.start();
        thread1.start();
        thread2.start();
    }
}

Output:

thread2 oops!
thread1 interrupted
thread0 interrupted

Further reading: https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop()+to+terminate+threads

walen
  • 7,103
  • 2
  • 37
  • 58
0

You could write the code to kill all the running threads in finally block or catch block(which might not be recommended)

On killing all the running threads,refer this thread

Community
  • 1
  • 1
karthik
  • 17
  • 2
-1

If I got you question correct, You need to catch the exception and need to keep/maintain the list as a shared object, then call thread.stop() on the other threads will solve the problem right? But the stop method is deprecated in recent versions of java, So you can use thread.yield() to make the thread release the CPU and other resources, But still it will not guarantee the immediate termination of threads.

Kiran Kumar
  • 1,033
  • 7
  • 20
  • currently all threads have thread.join. But if exception occurs in thread 1. thread 2 will still execute. i want if exception occurs in thread 1, then all threads who have thread1.join or even the threads who are not waiting for thread 1 should not execute. and the currently running threads also should stop – chumak Dec 21 '16 at 06:56
  • The call `thread.join()` will not guarantee that it will terminate the thread immediately, rather it will wait for the other threads to finish and return to it. – Kiran Kumar Dec 21 '16 at 07:25
  • [Thread.stop()](https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#stop--) has been deprecated for at least 20 years. – user207421 Dec 21 '16 at 07:29
  • 2
    `yield()` will do nothing to make the thread stop, it just says "I think this would be a good time to give some CPU to other tasks". – piet.t Dec 21 '16 at 07:39
  • 'Recent versions of Java' includes every version since at least May 1997. How recent is 'recent'? – user207421 Dec 21 '16 at 07:44