spring批处理作业已完成,但其线程从未被销毁

5hcedyr0  于 2021-07-23  发布在  Java
关注(0)|答案(1)|浏览(485)

我在spring批处理应用程序中有一个作业已成功完成,但完成后,其线程将进入等待状态。随着越来越多的作业示例被执行,tomcat的线程数量也在不断增加。
以下是作业配置:

@Bean
@Scope("singleton")
@Qualifier(value = "job1")
public Job job() {
    return jobBuilderFactory.get("job1")
            .incrementer(new RunIdIncrementer())
            .flow(step1())
            .end()
            .preventRestart()
            .build();
}

@Bean
public Step step1() {
    return stepBuilderFactory.get("step1")
            .<Buylead, Buylead>chunk(10000)
            .reader(itemReader())
            .writer(itemWriter())
            .build();
}

public JdbcCursorItemReader<Buylead> itemReader() {
    JdbcCursorItemReader<Buylead> reader = new JdbcCursorItemReader<>();

    reader.setDataSource(dataSource);
    reader.setSql(" --- WHatever Query ----");
    reader.setRowMapper(new MapperBL());

    return reader;
}

public ItemWriter<Buylead> itemWriter(){
    FlatFileItemWriter<Buylead> itemWriter = new FlatFileItemWriter() ;

    itemWriter.setResource(new FileSystemResource("output/buyleadSolrDoc.xls"));
    itemWriter.setLineAggregator(new DelimitedLineAggregator<Buylead>() { {
                setFieldExtractor(new BeanWrapperFieldExtractor<Buylead>() { {
                    setNames(new String[] {***************}); } }); } });
    itemWriter.setShouldDeleteIfEmpty(true);
    return itemWriter;
}

数据源保存在另一个配置类中。
这是主要课程

@SpringBootApplication
@EnableBatchProcessing
public class Application  extends DefaultBatchConfigurer{

    public static void main(String[] args) {
        SpringApplication.run(SearchApplication.class, args);
    }

    @Override
    public void setDataSource(DataSource dataSource) {
        // override to do not set datasource even if a datasource exist.
        // initialize will use a Map based JobRepository (instead of database)
    }

}

作业正在成功执行。但是它的线程进入等待状态。
下面是应用程序的threaddump部分

http-nio-8080-exec-2" #22 daemon prio=5 os_prio=0 cpu=0.11ms elapsed=29.43s tid=0x00007fcb6d6ddd60 nid=0xc724 waiting on condition  [0x00007fcae3ffe000]
   java.lang.Thread.State: WAITING (parking)
    at jdk.internal.misc.Unsafe.park(java.base@15.0.1/Native Method)
    - parking to wait for  <0x0000000713c00710> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(java.base@15.0.1/LockSupport.java:341)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@15.0.1/AbstractQueuedSynchronizer.java:505)
    at java.util.concurrent.ForkJoinPool.managedBlock(java.base@15.0.1/ForkJoinPool.java:3137)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@15.0.1/AbstractQueuedSynchronizer.java:1614)
    at java.util.concurrent.LinkedBlockingQueue.take(java.base@15.0.1/LinkedBlockingQueue.java:435)
    at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:108)
    at org.apache.tomcat.util.threads.TaskQueue.take(TaskQueue.java:33)
    at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@15.0.1/ThreadPoolExecutor.java:1056)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@15.0.1/ThreadPoolExecutor.java:1116)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@15.0.1/ThreadPoolExecutor.java:630)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(java.base@15.0.1/Thread.java:832)*

请建议关闭处于公园状态的线程的方法。

g6ll5ycj

g6ll5ycj1#

springbatch不直接创建或管理线程。它把它委托给 TaskExecutor 异地实施:
这个 JobLauncher 委托给任务执行器以启动作业
这个 StepBuilder 委托给任务执行器以创建多线程步骤
这个 FlowBuilder 委托给任务执行器以创建拆分流并并行运行步骤
这个 AsyncItemProcessor 委托给任务执行器以在不同的线程中异步处理项
这个 TaskExecutorPartitionHandler 委托给任务执行器以处理不同线程中的分区

在所有这些情况下,线程的生命周期都由底层线程管理 TaskExecutor 实施。如果将任务执行器与spring批处理一起使用,则需要确保在不再需要它时正确地停止/关闭它。从您共享的内容来看,您似乎没有在spring批处理配置中使用任务执行器,因此您应该在应用程序上下文中的某个位置定义一个未正确停止的任务执行器。

相关问题