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

处理ThreadPoolExecutor的异常

柯凯旋
2023-03-14
问题内容

我有以下代码片段,它们基本上扫描了需要执行的任务列表,然后将每个任务提供给执行程序以执行。

JobExecutor反过来又创造了另一个执行人(做数据库的东西…读取和写入数据队列),并完成任务。

JobExecutor返回Future<Boolean>提交的任务的。当任务之一失败时,我想适当地中断所有线程并通过捕获所有异常关闭执行程序。我需要做什么改变?

public class DataMovingClass {
    private static final AtomicInteger uniqueId = new AtomicInteger(0);

  private static final ThreadLocal<Integer> uniqueNumber = new IDGenerator();

  ThreadPoolExecutor threadPoolExecutor  = null ;

   private List<Source> sources = new ArrayList<Source>();

    private static class IDGenerator extends ThreadLocal<Integer> {
        @Override
        public Integer get() {
            return uniqueId.incrementAndGet();
        }
  }

  public void init(){

    // load sources list

  }

  public boolean execute() {

    boolean succcess = true ; 
    threadPoolExecutor = new ThreadPoolExecutor(10,10,
                10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1024),
                new ThreadFactory() {
                    public Thread newThread(Runnable r) {
                        Thread t = new Thread(r);
                        t.setName("DataMigration-" + uniqueNumber.get());
                        return t;
                    }// End method
                }, new ThreadPoolExecutor.CallerRunsPolicy());

     List<Future<Boolean>> result = new ArrayList<Future<Boolean>>();

     for (Source source : sources) {
                    result.add(threadPoolExecutor.submit(new JobExecutor(source)));
     }

     for (Future<Boolean> jobDone : result) {
                try {
                    if (!jobDone.get(100000, TimeUnit.SECONDS) && success) {
                        // in case of successful DbWriterClass, we don't need to change
                        // it.
                        success = false;
                    }
                } catch (Exception ex) {
                    // handle exceptions
                }
            }

  }

  public class JobExecutor implements Callable<Boolean>  {

        private ThreadPoolExecutor threadPoolExecutor ;
        Source jobSource ;
        public SourceJobExecutor(Source source) {
            this.jobSource = source;
            threadPoolExecutor = new ThreadPoolExecutor(10,10,10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1024),
                    new ThreadFactory() {
                        public Thread newThread(Runnable r) {
                            Thread t = new Thread(r);
                            t.setName("Job Executor-" + uniqueNumber.get());
                            return t;
                        }// End method
                    }, new ThreadPoolExecutor.CallerRunsPolicy());
        }

        public Boolean call() throws Exception {
            boolean status = true ; 
            System.out.println("Starting Job = " + jobSource.getName());
            try {

                        // do the specified task ;


            }catch (InterruptedException intrEx) {
                logger.warn("InterruptedException", intrEx);
                status = false ;
            } catch(Exception e) {
                logger.fatal("Exception occurred while executing task "+jobSource.getName(),e);
                status = false ;
            }
           System.out.println("Ending Job = " + jobSource.getName());
            return status ;
        }
    }
}

问题答案:

将任务提交给执行者时,它会返回一个FutureTask实例。

FutureTask.get()会将任务抛出的所有异常重新抛出为ExecutorException

因此,当您遍历List<Future>并分别调用get时,捕获ExecutorException并调用有序关闭。



 类似资料:
  • 本文向大家介绍浅谈java异常处理(父子异常的处理),包括了浅谈java异常处理(父子异常的处理)的使用技巧和注意事项,需要的朋友参考一下 我当初学java异常处理的时候,对于父子异常的处理,我记得几句话“子类方法只能抛出父类方法所抛出的异常或者是其子异常,子类构造器必须要抛出父类构造器的异常或者其父异常”。那个时候还不知道子类方法为什么要这样子抛出异常,后来通过学习《Thinking in Ja

  • 我对Spring批处理跳过逻辑有一些问题。我已经配置了一个作业的步骤来跳过两个异常(SQLIntegrityConstraintViolation异常和乐观锁定失败异常): 但当作业运行时,由于我将其配置为跳过的异常,作业以未知状态完成: 我做错什么了吗?我希望这一步跳过负责抛出其中一个异常的项,并继续处理,以便以完成状态结束。

  • 我不知道该怎么办。 当我试图从解析器获取语法错误的数量时,它显示0。 编辑: 它返回null。

  • Blade 内置了 异常处理器,在开发者模式下它会将异常输出在前端页面,并在控制台打印堆栈信息,生产环境只打印在控制台。 有些时候不满足我们的需求,这时候就需要自定义异常处理了,比如针对某个自定义的异常进行特殊处理。 我们用一个例子来解释如何操作。 定义了一个名为 TipException 的运行时异常类,用于输出错误消息到前台。 按照上面对异常的处理情况这个异常的堆栈信息会被输出在控制台,生产环

  • 任何方法都可以抛出不同类型的异常。这些异常可能是需要应用程序重新部署来解决的编程错误,或者是不需要重新部署但可以解决的暂时性错误。 Hangfire可以处理所有内部的(属于Hangfire本身)和相关的外部方法(任务,过滤器等)的异常,因此不会导致整个应用程序被关闭。所有内部异常都被记录(所以不要忘记 启用日志),最糟糕的情况是导致后台任务被暂停并延时重试 10 次。 当Hangfire遇到在执行

  • 我们在编写程序的时候,经常需要对异常情况做处理。比如,当一个数试图除以 0 时,我们需要捕获这个异常情况并做处理。你可能会使用类似 if/else 的条件语句来对异常情况做判断,比如,判断除法的分母是否为零,如果为零,则打印错误信息。 这在某些简单的情况下是可以的,但是,在大多数时候,我们应该使用 Python 的异常处理机制。这主要有两方面的好处: 一方面,你可以选择忽略某些不重要的异常事件,或