【问题标题】:If one thread throwing an exception then How to stop other waiting threads如果一个线程抛出异常,那么如何停止其他等待线程
【发布时间】:2018-05-21 02:19:22
【问题描述】:

在 Java 中如果我有三个线程 t1,t2t3。假设 t1 正在执行某个任务,而 t2,t3 处于等待状态。现在如果 t1 面临/抛出任何类型的异常,那么我不想执行我的 t2,t3 线程。

我们如何在 Java 中实现这个功能?

【问题讨论】:

  • 不要使用线程,使用执行器框架。
  • @AndyTurner。一方面这是个好建议。另一方面,很高兴了解内部如何通过较低级别的对象工作。如果 OP 在自己的研究中投入一些精力,这将是一个很好的问题。

标签: java multithreading exception exception-handling


【解决方案1】:

不要直接使用线程,使用执行器框架。

具体来说,使用CompletionService,以便您可以按完成顺序(成功或其他)检索您提交给执行者的任务。

代替:

Thread t1 = new Thread(() -> { /* runnable 1 */ });
Thread t2 = new Thread(() -> { /* runnable 2 */ });
Thread t3 = new Thread(() -> { /* runnable 3 */ });

创建CompletionService

ExecutorService executor = ...;  // e.g. Executors.newFixedThreadPool
CompletionService completionService = new CompletionService(executor);

现在,创建一个列表来保存通过向CompletionService 提交任务返回的Futures:

List<Future<?>> futures = new ArrayList<>();
futures.add(completionService.submit(() -> { /* runnable 1 */ })); 
futures.add(completionService.submit(() -> { /* runnable 2 */ })); 
futures.add(completionService.submit(() -> { /* runnable 3 */ }));

现在,使用take 按完成顺序获取期货:

for (int i = 0; i < futures.size(); ++i) {
  Future<?> completed = futures.take();
  try {
    completed.get();
  } catch (ExecutionException e) {
    // An exception occurred whilst running the task.
    // Cancel all the tasks.
    futures.forEach(f -> f.cancel(true));
  }
}

当然,为了让cancel 在这里做任何有用的事情,你需要你的 runnables 来检查中断;但无论如何你都需要有一些方法来检查你的其他线程中的“失败”。

【讨论】:

  • 我认为,与其迭代 futures 列表,不如使用 poll()ing completionService。不过不太确定,也没有测试。
猜你喜欢
  • 2022-07-19
  • 1970-01-01
  • 2011-05-28
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-22
相关资源
最近更新 更多