异步处理就是:如果一条数据正在处理,后面又来了一条数据,可以不用等前面的数据处理完进行处理。异步处理也是用多线程实现的,但与上章节在step中使用多线程有所不同,多线程方式:每个线程处理一批数据,互不干扰,开辟晚的线程有可能比开辟早的线程先执行完毕;异步方式:异步方式按读取数据的先后顺序执行,读取一批数据后交给线程处理,又读取一批数据后,如果前面的数据还没执行完毕,可以不用等待,从线程池中拿新的线程执行。多线程方式有可能处理数据的方式不是按读取数据的先后顺从执行的。
@Bean
public Step chunkStep(){
return stepBuilderFactory.get("chunkStep")
.chunk(3)
.reader(new FileItemReader()) /*FileItemReader实现ItemReader,覆盖reader方法时要在方法前加synchronized同步,避免数据重复读*/
.processor(new UserAsyncItemProcessor())
.writer(new UserAsyncItemProcessor())
.allowStartIfComplete(true)
.taskExecutor(taskExecutor())
.build();
}
/*设置线程池*/
@Bean
public ThreadPoolTaskExecutor taskExecutor(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds);
return threadPoolTaskExecutor;
}
/*设置异步处理*/
@Bean
public AsyncItemProcessor asyncUserProcessor() throws Exception {
AsyncItemProcessor<List<User>, List<User>> asyncItemProcessor = new AsyncItemProcessor<>();
asyncItemProcessor.setDelegate(new UserItemProcessor()); //UserItemProcessor实现ItemProcessor接口
asyncItemProcessor.setTaskExecutor(taskExecutor());
asyncItemProcessor.afterPropertiesSet(); //检验参数设置
return asyncItemProcessor;
}
/*设置异步写*/
@Bean public AsyncItemWriter asyncUserWriter() throws Exception {
AsyncItemWriter<List<User>> asyncItemWriter = new AsyncItemWriter<>();
asyncItemWriter.setDelegate(new UserItemWriter()); //UserItemWriter实现ItemWriter接口
asyncItemWriter.afterPropertiesSet();
return asyncItemWriter;
}