当一个线程失败时停止ExecutorService线程。 &安培;返回异常

时间:2015-05-07 21:44:29

标签: java multithreading exception-handling threadpool threadpoolexecutor

如果任何提交的线程抛出异常,则不返回异常。

我想为我的项目编写一段代码,如果任何线程执行失败,它应该在那里抛出异常&它应该停止所有的运行&预定的线程。

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

我像这样写了MyObject ..,

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

这是我的目标的正确实现...... ????? 我想实现这个目标,请给我一些指示。

提前致谢.... !!

1 个答案:

答案 0 :(得分:3)

这是你可以考虑的事情。这里我使用CallableTask而不是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);
                }
            }
      }

这里我使用两个类来证明这是有效的。当一个任务抛出异常时,永久运行的任务也会停止运行。

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);

        }
    }
}

但这有其自身的局限性。由于&#34; future.get()&#34;此代码将等待它抛出异常。顺序执行。

最佳案例:在第一个future.get()中抛出异常,其他任务将被取消。

最坏情况:在最后future.get()中抛出一个异常,然后抛出异常执行所有其他任务。

优化:识别可以引发异常的任务,并等待这些任务仅取消所有其他任务。

如果您的运行方法在其中有,那么最好的方式是共享一个标志并打破它。查看this答案以获取更多信息。