gpt4 book ai didi

Java "finalize"线程异常

转载 作者:行者123 更新时间:2023-11-30 07:30:23 25 4
gpt4 key购买 nike

我正在使用多个线程对大型数据集执行一些繁重(且容易出错)的处理。我要求所有线程都完成执行,无论它们是抛出异常还是正常终止(没有返回值),然后程序才能继续。我正在使用 CountDownLatch 来实现这一点,并使用 ExecutorService 来实际运行作业。我希望工作线程(为了便于讨论,我们称它们为 JobManager-s)通知锁存器,即使它们抛出异常也是如此。 JobManager 可能需要一秒到一小时才能完成,并且随时可能失败。这个想法是在抛出异常时调用 JobManager 的“finalizer”方法。现在,ExecutorService 喜欢捕获异常或隐藏异常的真正来源。我有几种解决方法,但都不令人满意:

  1. 使用 ExecutorService#execute(Runnable r) 而不是 submit(Runnable r)。我可以这样做,因为我不关心 JobManager 的返回值。我提供了一个自定义的 ThreadFactory,它将一个 UncaughtExceptionHandler 附加到每个新创建的线程。这种方法的问题在于,当 UncaughtExceptionHandler#uncaughtException(Thread t, Throwable e) 被调用时,tRunnable 是类型 ThreadPoolExecutor$Worker,而不是 JobManager 类型,这会阻止我调用“finalizer”方法。

  2. 使用自定义 ExecutorService 并覆盖 afterExecute(Runnable r, Throwable t) 方法。这与 1 存在相同的问题。

  3. 将整个 JobManager#doWork() 包装在 catch 语句中,并使用返回值指示是否抛出异常。然后我可以提交 作业并使用FutureTask#get() 来决定是否抛出异常。我不喜欢这个解决方案,因为当你有一个精心设计的异常机制时,我觉得返回代码是错误的工具。此外,get() 会等待(除非被中断),这意味着我无法立即处理其他线程中的错误。

  4. 去掉 CountDownLatch。将所有 Future 存储在一个列表中并反复插入,直到我对这些状态感到满意为止。这可能行得通,但感觉像是一个肮脏的 hack。

非常感谢任何建议。

最佳答案

据我所知,您可以使用一个简单的 try-finally block :

public class JobManager {
public void doWork() {
try {
...
} finally {
countDownLatch.countDown();
}
}
}

关于Java "finalize"线程异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7893019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com