繁体   English   中英

Java在异常中“完成”线程

[英]Java “finalize” thread on exception

我正在使用多个线程对大型数据集进行一些繁重(且容易出错)的处理。 我要求所有线程都可以完成执行,无论它们是否引发异常或正常终止(不返回任何值),然后程序才能继续执行。 我正在使用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语句中,并使用返回值指示是否引发了异常。 然后,我可以submit作业并使用FutureTask#get()来确定是否引发了异常。 我不喜欢这种解决方案,因为当您拥有精心设计的异常机制时,我觉得返回码是错误的工具。 而且, get()将等待(除非被中断),这意味着我无法立即处理其他线程中的错误。

  4. 摆脱CountDownLatch 将所有Future都存储在列表中,并反复戳入,直到对状态感到满意为止。 这可能有效,但感觉像是一个肮脏的hack。

任何建议,不胜感激。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM