Spring批处理:与有状态bean并行执行作业的多个实例

这是我的用例:

我有一个代码库(有状态),我想并行执行我的spring批处理作业,同时处理多个记录的数据 . 但由于我的库是非线程安全的,因此如果不添加自定义设置,就不可能使用多线程来运行批处理 .

此外,在作业的ItemProcess期间调用代码库 .

这是我到目前为止所尝试的:

  • 我在每个有状态的java文件中添加了 @Scope("step") . 除了性能大大降低之外,这在parellel中工作得很好 . 即使只有一个线程,在有状态bean中使用 @Scope("step") 也会降低性能 .

例如:1个线程中的100个数据,没有 @Scope("step") 在2分钟内处理数据 . 1个线程中的100个数据,4分钟内有 @Scope("step) 过程数据 .

(我不知道在使用 @Scope("step") 时是否添加了开销)

  • 对于我收到/读取的每个数据,我创建一个新的 ClassPathXmlApplicationContext 并使用一个带有 ThreadPoolTaskExecutor 的JobLauncher,但不知怎的,我在运行时得到 NullPointerException . 即使仍未调用init()方法,似乎已经调用了一些方法 . init()方法由服务类调用以初始化有状态作业的数据 . 我还验证了我确实在每个线程中创建了代码库的新实例(通过检查对象的hashCode来验证),但我无法按顺序执行方法 . 请注意,JobLauncher在每个applicationContext中声明 .

  • 我删除了JobLauncher并将其放在父applicationContext中以拥有一个JobLauncher单例 . 我仍在为每个数据创建applicationContext,但我在创建期间添加了父applicationContext . JobLauncher仍然是 ThreadPoolTaskExecutor 但是我将我的工作的tasklet的 tasklet-executor 设置为 SyncTaskExecutor . 当我运行它时,它会在某个时候冻结(我日食中的控制台已经停止更新)

尽管如此,我不想重构库代码以将其更改为线程安全,因为这个库是由另一个团队制作的 .

在多线程环境中处理有状态bean时,最佳方法应该是什么?

提前致谢 .

回答(0)