Spring批处理 - 如何使用ThreadPoolTask​​Executor

时间:2016-08-12 19:20:53

标签: java concurrency spring-batch

我对Spring-Batch相当新,所以这可能是我缺乏理解。我想知道如何在我的作业运行时使用ThreadPoolTask​​Executor和ThreadPoolExecutor动态增加和减少线程。我试图将ThreadPoolTask​​Executor和ThreadPoolExecutor子类化,这样我就可以访问beforeExecute()和afterExecute(),如果使用此站点上列出的方法减少了corepoolsize,我将终止线程。

我似乎不理解的是,当我覆盖返回ExecutorService的initializeExecutor()方法时,它显然没有在父类(ThreadPoolTask​​Executor)中设置(private internal)threadPoolExecutor变量。它设置了私有的ExecutorService执行器; (来自ExecutorConfigurationSupport类)

由于threadPoolExecutor不是受保护的成员,因此我无法访问它。如果没有设置,当我运行时,我明显最终在Spring框架中得到一个“ThreadPoolExecutor not initialized”错误,当我检查内幕中的错误时。

public class MyThreadPoolTask​​Executor扩展了ThreadPoolTask​​Executor {

@Override
protected ExecutorService initializeExecutor(ThreadFactory tf, RejectedExecutionHandler reh)
{

    BlockingQueue <Runnable> queue = createQueue(Integer.MAX_VALUE);

    MyThreadPoolExecutor tp_executor = new MyThreadPoolExecutor( this.getCorePoolSize(), this.getMaxPoolSize(),     this.getKeepAliveSeconds(), TimeUnit.SECONDS, queue);

    // if you look at the parent class(ThreadPoolTaskExecutor) it performs this call next.
    //  this.threadPoolExecutor = executor;
    // that is a private member with no ability to set via any methods.

    return tp_executor;
}

}

public class MyThreadPoolExecutor扩展了ThreadPoolExecutor {

public MyThreadPoolExecutor(int corePoolSize, int maxPoolSize, long keepAliveTimeout, TimeUnit timeunit, BlockingQueue<Runnable> workQueue, ThreadFactory tf, RejectedExecutionHandler reh) 
{
    super(corePoolSize, maxPoolSize, keepAliveTimeout, timeunit, workQueue, tf, reh);
}

protected void beforeExecute (final Thread thread, final Runnable job) 
{   
  ...
}

}

有人可以解释我的方法中缺少的内容吗?

1 个答案:

答案 0 :(得分:1)

我假设你想在一个作业步骤中使用一个线程,在另一个作业步骤中使用另一个线程数。实现这一目标的简单方法是声明两个具有必要线程数的独立执行程序,零corePoolSize(在不需要时不创建线程)和零keepAliveSeconds(当不是这样时,不保留线程)不再需要)。然后在一步中注入第一个执行程序,在另一步中注入第二个执行程序。

@Configuration
public class Conf {

    @Bean
    public TaskExecutor executorA(@Value("${first.number.of.threads}") int numberOfThreads) {
        return executor(numberOfThreads);
    }

    @Bean
    public TaskExecutor executorB(@Value("${second.number.of.threads}") int numberOfThreads) {
        return executor(numberOfThreads);
    }

    private TaskExecutor executor(int numberOfThreads) {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(0);
        executor.setMaxPoolSize(numberOfThreads);
        executor.setAllowCoreThreadTimeOut(true);
        executor.setKeepAliveSeconds(0);
        return executor;
    }
}