Java 爪哇语;定稿;线程异常

Java 爪哇语;定稿;线程异常,java,multithreading,Java,Multithreading,我正在使用多个线程对一个大数据集进行一些繁重(而且容易出错)的处理。我要求所有线程完成执行,不管它们是否抛出异常或正常终止(不返回值),然后程序才能继续。我正在使用countdownlock来实现这一点,并使用ExecutorService来实际运行作业。我希望工作线程(为了参数起见,我们称它们为JobManager-s)通知闩锁,即使它们抛出异常。JobManager可以在一秒钟到一小时之间的任何时间完成,并且随时可能失败。其思想是在抛出异常时调用JobManager的“finalizer”方

我正在使用多个线程对一个大数据集进行一些繁重(而且容易出错)的处理。我要求所有线程完成执行,不管它们是否抛出异常或正常终止(不返回值),然后程序才能继续。我正在使用
countdownlock
来实现这一点,并使用
ExecutorService
来实际运行作业。我希望工作线程(为了参数起见,我们称它们为
JobManager
-s)通知闩锁,即使它们抛出异常。
JobManager
可以在一秒钟到一小时之间的任何时间完成,并且随时可能失败。其思想是在抛出异常时调用
JobManager
的“finalizer”方法。现在,
ExecutorService
喜欢捕捉异常,或者隐藏它没有发现的异常的真正来源。我想了几种方法来解决这个问题,但都不令人满意:

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

  • 使用自定义
    ExecutorService
    并重写
    afterExecute(Runnable r,Throwable t)
    方法。这与1的问题相同

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

  • 摆脱
    倒计时闩锁
    。将所有
    Future
    s存储在列表中,并反复插入,直到我对状态感到满意为止。这可能有用,但感觉像是一个肮脏的黑客


  • 非常感谢您的建议。

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

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

    我知道这不是很有帮助,但是+1用于非常好的格式设置。其思想并不是“在引发异常时调用JobManager的“finalizer”方法”。这只是一种可能的实现。我们的想法是,实际上没有最终确定的方法。我强烈建议你重写你的标题来表达你的实际问题。