【发布时间】:2021-11-09 12:09:49
【问题描述】:
这是我为暴露我的问题所做的一个简化示例。我有一些任务doSomeWork(),我使用 ExecutorService 以多线程方式处理(一次最多 4 个线程)。但是,如果任何线程/任务产生异常,我想:
-
停止处理任何进一步的任务。
-
在主线程级别捕获异常。
public static void main(String[] args) { final ExecutorService threadPool = Executors.newFixedThreadPool(4); final ExecutorCompletionService<Void> completionService = new ExecutorCompletionService<>(threadPool); try { for (int i = 0; i < 10; i++) { int b = i; completionService.submit(() -> doSomeWork(b)); } threadPool.shutdown(); threadPool.awaitTermination(8, TimeUnit.HOURS); System.exit(0); } catch (Exception e) { System.out.println("Something wrong happened: " + e.getMessage()); } System.exit(1); } //This function have 50% odds of throwing an exception public static Void doSomeWork(int i) throws Exception { Thread.sleep(500); if ((Math.random() > 0.5)) { System.out.println("I have reached indice: " + i); } else { throw new Exception("I couldn't handle indice " + i); } return null; }
目前,执行会输出如下内容:
I have reached indice: 0
I have reached indice: 2
I have reached indice: 1
I have reached indice: 4
I have reached indice: 6
I have reached indice: 7
I have reached indice: 5
I have reached indice: 9
如您所见,indice 3 丢失了,但剩余线程的执行已完成。它也没有输出任何关于异常的信息。
我想要的输出是这样的:
I have reached indice: 0
I have reached indice: 2
I have reached indice: 1
Something wrong happened: I couldn't handle indice 3
我围绕这个问题找到的其他解决方案是使用带有未来但以阻塞方式的可调用对象。我不能在等待未来的同时阻止其他线程的执行,否则整个多线程是没有意义的。
【问题讨论】:
-
请在发帖前检查您的问题,并始终添加所有相关标签。
-
你提交给线程池的任务被封装成
FutureTask,执行过程中出现的任何异常都会被FutureTask#run方法捕捉到,所以需要要么把异常捕捉到里面任务或从返回的 Future#get 中获取它。 -
"我不能在等待未来时阻止其他线程的执行......" 使用 future.get 不会阻止其他线程的执行。它可以以与您使用“awaitTermination”相同的方式使用。它会在其他线程正在执行时阻塞主线程。
标签: java multithreading exception