完成后,分区工作不能自行停止? 春批
我写了两个步骤的作业,其中两个步骤之一是分区步骤。 分区步骤使用TaskExecutorPartitionHandler并在线程中运行5个从属步骤。 该作业在main()方法中启动。 但是在每个从属ItemReader返回null(结束符号)之后它不会停止。 即使程序运行了main()方法中的最后一行代码(即System.out.println(“Finished”)),程序进程也不会停止,挂在内存中并且什么都不做。 我必须按下Eclipse面板上的停止按钮才能停止程序。
以下是JobLauncher.run()返回的JobExecution的内容,表示作业运行的成功状态。
JobExecution:id = 0,version = 2,startTime = Fri Nov 27 06:05:23 CST 2015,endTime = Fri Nov 27 06:05:39 CST 2015,lastUpdated = Fri Nov 27 06:05:39 CST 2015,status = COMPLETED,exitStatus = exitCode = COMPLETED; exitDescription =,job = [JobInstance:id = 0,version = 0,Job = [jobCensoredPages]],jobParameters = [{}]
7217
成品
为什么运行成功的Spring Batch程序仍然挂起? 请指出我在哪里工作。 我怀疑Spring Batch管理的multithreading部分没有停止..
简单的工作运行代码
Job job = (Job) context.getBean("jobPages"); try { JobParameters p=new JobParametersBuilder() .toJobParameters(); JobExecution result = launcher.run(job, new JobParameters()); System.out.println(result.toString()); } catch (Exception e) { e.printStackTrace(); } context.getBean("idSet"); AtomicInteger n=(AtomicInteger) context.getBean("pageCount"); System.out.println(n.get()); System.out.println("Finished");
对Patitioner和PatitionHandler的配置
@Bean @Autowired public PartitionHandler beanPartitionHandler( TaskExecutor beanTaskExecutor, @Qualifier("beanStepSlave") Step beanStepSlave ) throws Exception { TaskExecutorPartitionHandler h=new TaskExecutorPartitionHandler(); h.setGridSize(5); h.setTaskExecutor(beanTaskExecutor); h.setStep(beanStepSlave); h.afterPropertiesSet(); return h; } @Bean public TaskExecutor beanTaskExecutor() { ThreadPoolTaskExecutor e = new ThreadPoolTaskExecutor(); e.setMaxPoolSize(5); e.setCorePoolSize(5); e.afterPropertiesSet(); return e; }
唯一的一步,它是奴隶的一步
@Bean public Step beanStepMaster( Step beanStepSlave, Partitioner beanPartitioner, PartitionHandler beanPartitionHandler ) throws Exception { return stepBuilderFactory().get("stepMaster") .partitioner(beanStepSlave) .partitioner("stepSlave", beanPartitioner) .partitionHandler(partitionHandler) .build(); } @Bean @Autowired public Step beanStepSlave( ItemReader beanReaderTest, ItemProcessor beanProcessorTest, ItemWriter beanWriterTest) throws Exception{ return stepBuilderFactory().get("stepSlave") .chunk(1) .reader(beanReaderTest) .processor(beanProcessorTest) .writer(beanWriterTest) .build(); }
我的pom.xml文件
junit junit RELEASE test org.springframework spring-core 4.2.3.RELEASE org.springframework spring-context 4.2.3.RELEASE org.springframework spring-tx 4.2.3.RELEASE org.springframework.batch spring-batch-core RELEASE org.springframework.retry spring-retry 1.1.2.RELEASE org.springframework spring-beans RELEASE
当我使用ThreadPoolTaskExecutor时,我在分区的Spring批处理应用程序挂起时也遇到了困难。 另外,我看到执行程序不允许完成所有分区的工作。
我找到了解决这些问题的两种方法。
第一种解决方案是使用SimpleAsyncTaskExecutor而不是ThreadPoolTaskExecutor。 如果您不介意重新创建线程的额外开销,这是一个简单的修复。
第二个解决方案是创建一个JobExecutionListener,它在ThreadPoolTaskExecutor上调用shutdown。
我创建了一个JobExecutionListener,如下所示:
@Bean public JobExecutionListener jobExecutionListener(ThreadPoolTaskExecutor executor) { return new JobExecutionListener() { private ThreadPoolTaskExecutor taskExecutor = executor; @Override public void beforeJob(JobExecution jobExecution) { } @Override public void afterJob(JobExecution jobExecution) { taskExecutor.shutdown(); } }; }
并将其添加到我的Job定义中,如下所示:
@Bean public Job partitionedJob(){ return jobBuilders.get("partitionedJob") .listener(jobExecutionListener(taskExecutor())) .start(partitionedStep()) .build(); }
虽然我不知道原因,但有两种解决方案可以解决您的问题。
首先,您可以使用CommandLineJobRunner
来启动Job
。 请参阅此处的文档 该类在作业结束时自动退出程序,并将ExitStatus转换为返回代码( COMPLETED
= 0, FAILED
= 1 …)。 默认返回码由SimpleJvmExitCodeMapper
提供。
第二种解决方案是在JobLauncher.run()
之后手动调用System.exit()
指令。 您也可以手动转换Job
的ExitStatus
并在手动退出中使用它:
// Create Job JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher"); Job job = (Job) context.getBean(jobName); // Create return codes mapper SimpleJvmExitCodeMapper mapper = new SimpleJvmExitCodeMapper(); // Start Job JobExecution execution = jobLauncher.run(job, new JobParameters()); // Close context context.close(); // Map codes and exit String status = execution.getExitStatus().getExitCode(); Integer returnCode = mapper.intValue(status); System.exit(returnCode);
- 多个一对多关系ResultSetExtractor
- 我应该尝试在Java中创建可逆枚举还是有更好的方法?
- 如何通过所有可能性增加java String?
- 从JSF中的Datatable获取选定的行数据
- 使用AwesomeFont中的自定义字体和Java Swing中的unicode字符向JButton添加图标?
- 当我创建对象的新实例作为键时,Java HashMap.get()返回null
- Quartz Scheduler突然停止运行,没有exception错误
- 怎么可能,3个线程处于阻塞状态,等待同一个监视器,并且没有线程拥有该监视器
- Apache CXF客户端在Eclipse中加载正常,但独立的jar在WSDLServiceFactory中抛出NullpointerException