当前位置: 首页 > 面试题库 >

处理来自Java ExecutorService任务的异常

钮刚洁
2023-03-14
问题内容

我正在尝试使用Java的ThreadPoolExecutor类来运行大量具有固定数量线程的重量级任务。每个任务都有很多地方,在这些地方可能会由于异常而失败。

我已经继承了子类,ThreadPoolExecutor并且重写了afterExecute应该提供运行任务时遇到的任何未捕获异常的方法。但是,我似乎无法使其工作。

例如:

public class ThreadPoolErrors extends ThreadPoolExecutor {
    public ThreadPoolErrors() {
        super(  1, // core threads
                1, // max threads
                1, // timeout
                TimeUnit.MINUTES, // timeout units
                new LinkedBlockingQueue<Runnable>() // work queue
        );
    }

    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if(t != null) {
            System.out.println("Got an error: " + t);
        } else {
            System.out.println("Everything's fine--situation normal!");
        }
    }

    public static void main( String [] args) {
        ThreadPoolErrors threadPool = new ThreadPoolErrors();
        threadPool.submit( 
                new Runnable() {
                    public void run() {
                        throw new RuntimeException("Ouch! Got an error.");
                    }
                }
        );
        threadPool.shutdown();
    }
}

该程序的输出是“一切都很好-情况正常!” 即使唯一提交给线程池的Runnable引发异常。任何线索这里发生了什么?

谢谢!


问题答案:

提交Runnable时,它将被包装在Future中。

你的afterExecute应该是这样的:

public final class ExtendedExecutor extends ThreadPoolExecutor {

    // ...

    protected void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if (t == null && r instanceof Future<?>) {
            try {
                Future<?> future = (Future<?>) r;
                if (future.isDone()) {
                    future.get();
                }
            } catch (CancellationException ce) {
                t = ce;
            } catch (ExecutionException ee) {
                t = ee.getCause();
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }
        }
        if (t != null) {
            System.out.println(t);
        }
    }
}


 类似资料:
  • 问题内容: 我正在寻找可以提供超时的ExecutorService实现。如果提交到ExecutorService的任务花费的时间超过了超时时间,则这些任务将被中断。实现这样的野兽并不是一个困难的任务,但是我想知道是否有人知道现有的实现。 这是我根据以下一些讨论得出的。任何意见? 问题答案: 你可以为此使用ScheduledExecutorService。首先,你只提交一次即可立即开始,并保留创建的

  • 我一直在研究Spring集成文件支持,在这里我需要将文件从输入目录移动到输出目录。成功地将其移动到输出目录后,应该将其归档,然后从输入目录中删除。我正在使用下面的配置来实现这一点。 请纠正我,如果我的配置可以更好的方式。 Spring集成配置: 我在服务激活器中有代码,如果归档目录不可用,它应该终止应用程序。因此,在运行应用程序时,在第一次移动文件后,我已经删除了归档目录。然后,我将新文件放置在i

  • 我尝试使用Windows 10任务计划程序计划一个作业来运行批处理文件,但它导致返回代码2147942401。 批处理文件位于远程位置,因此我给出了绝对路径< br >“\ \ server 1 \ file transfers \ data files \ inbound \ ABC \ CSV \ excel-to-CSV . bat” 批处理脚本用于将 Excel 转换为文件到 csv。 脚

  • 我试图弄清楚如何处理从返回的数据。 我有一个活动,我正在调用异步Firebase get操作(存在于其他类中的操作),并且我想使用检索到的ArrayList的大小更新活动中存在的。以下是我在活动创建中获取的 Firebase 调用: 这是我的Firebase操作: 在Android中,最好的方法是什么?是否有可能实现各种适配器或完成处理程序?

  • 问题内容: 等待所有任务完成的最简单方法是什么?我的任务主要是计算,所以我只想运行大量的作业-每个内核上一个。现在,我的设置如下所示: 实现可运行。这似乎是正确执行的任务,但代码崩溃上用。这很奇怪,因为我玩了一些玩具示例,而且看起来很奏效。 包含数以万计的元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西 问题答案: 最简单的方法是使用单行代码执行所需的操作。用你的话来说,你需要修改或包装以实

  • 我正在使用执行器服务并行运行任务。并行运行方法采用输入整数并返回整数 。由于并行任务具有返回类型,因此我使用了可调用的匿名类。您可以在下面的示例中看到 是从 executer 调用的。任务方法也有1秒的等待时间,并为抛出异常; 在下面的实现中,我使用invokeAll和isDone,并尝试收集数据。 下面的程序抛出。 未来任务迭代和检查有什么问题 isDone 和 get() 。如何处理特定调用的