anji_rajesh
anji_rajesh

Reputation: 369

Stop ExecutorService threads when one thread fails. & return the exception

If any of the submitted thread is throwing exception its not returning the exception.

I want to write a piece of code for my project where in if any of the thread execution is failed it should throw the exception there & it should stop all the running & scheduled threads.

ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
 Thread t = new Thread(new MyObject());
 executorService.submit(t);
}

I wrote MyObject like this..,

public class MyObject implements Runnable {   
    public void run() {
         throw new NullPointerException("Sample NullPointerException");
    }
}

Is this the correct implementation for my goal...????? i want to achieve that goal please give me some pointers.

Thanks In Advance....!!

Upvotes: 5

Views: 7235

Answers (1)

Eranda
Eranda

Reputation: 1467

Here is something you can consider about. Here I am using CallableTask instead of Thread.

    public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            Set<Future<Void>> futureSet = new HashSet<Future<Void>>();

            for (int i = 0; i < 9; i++) {
                CallableTask1 task = new CallableTask1();
                futureSet.add(executorService.submit(task));
            }

            CallableTask2 task2 = new CallableTask2();
            futureSet.add(executorService.submit(task2));

            boolean flag = false;
            for (Future<Void> future : futureSet ) {
                try {
                    future.get();
                } catch (InterruptedException e) {
                    System.out.println("Interrupted");
                } catch (ExecutionException e) {
                    System.out.println("Exception thrown from the thread");
                    flag = true;
                    break;
                }
            }

            if(flag) {
                for (Future<Void> future : futureSet) {
                    future.cancel(true);
                }
            }
      }

Here I am using two classes to demonstrate this is working. When one task throw an exception the forever running task is also stop running.

class CallableTask1 implements Callable<Void> {

    @Override
    public Void call() throws Exception {
        throw new NullPointerException("Sample NullPointerException");
    }
}


class CallableTask2 implements Callable<Void> {

    @Override
    public Void call() throws Exception {
        while (true){
            System.out.println("THIS IS RUNNING");
            Thread.sleep(5000);

        }
    }
}

But this has it's own limitations. This code will wait for it's turn to throw an exception because of "future.get()" executed sequentially.

Best case : Throw an exception in first future.get() and other tasks will be cancelled.

Worst case : Throw an exception in the last future.get() and by the time throw an exception all other tasks done with execution.

Optimizing : Identify the tasks that can throw an exception and wait for those tasks only to cancel all the other tasks.

If your run methods has while in it then best way share a flag and break on it. Check this answer for more information.

Upvotes: 5

Related Questions