springbatch并行 springbatch多线程_线程池


在Spring Batch 中开启多线程需要两个两个值:

  • throttleLimit:线程数(最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目)
  • taskExecutor:如果是多线程,需要将这个参数设置成线程池,默认是一个简单异步执行器

现在我们开始今天的Demo, 这个Demo实现一个SB功能,就是多线程从数据库读出来数据,然后在Writer答应出读出的对象。

话不多说,先创建一个Spring -Batch的工程(SpringBatch从入门到放弃001- HelloWorld)。

配置一个Reader,我们选用JdbcPagingItemReader,这里需要注意的是对于多线程Batch,需要考虑Reader的线程安全问题,因为在多线程情况下,会导致Reader中的 如果你还不知道那些Reader 实现线程安全的,可以参考另一文章:SpringBatch从入门到放弃006- ItemReader


springbatch并行 springbatch多线程_springbatch并行_02


其实实现Reader线程安全问题非常简单,我们打开JdbcPagingItemReader的源码,在Javadoc 里面是这样描述:这是一个线程安全的实现在调用open()方法之间,如果在多线程中使用,需要设置saveState=false(但是这样就会不支持重启)。


springbatch并行 springbatch多线程_线程池_03


那么他是如何线程安全的呢?,继续看源码,在AbstractPagingItemReader.doRead()方法中我们看到了synchronized,这里是不是恍然大悟?


springbatch并行 springbatch多线程_线程安全_04


Processor 没有要求是线程安全的,所以定义成普通的就好了, Writer 要求线程安全,但是我们需求不需要线程安全,所以也定义成常规的就好了。


springbatch并行 springbatch多线程_openmp设置线程数目_05


核心的配置来了,我们首先定义了一个线程池ThreadPoolTaskExecutor,然后将这个任务执行线程池定义到Step中去,在给step 设置throttleLimit 设置成5。这样就实现了多线程。


springbatch并行 springbatch多线程_线程安全_06


我们注意到reader是分页读,每次读取3个元素,chunkSize 是 5 ,代表每五次写一次,那么Reader/Processor/Writer 是怎么匹配执行的呢?这里先卖个关子后边的章节我们会说到。

定义一个Junit,查看运行结果。


springbatch并行 springbatch多线程_多线程_07


我们可以看到多个线程在执行Job。


springbatch并行 springbatch多线程_openmp设置线程数目_08


这一节只是简单介绍一个Spring Batch 多线程的配置,下个章节鹏哥将通过源码,像大家展示,Spring Batch 多线程是怎么实现的。