这是我的用例:
我有一个代码库(有状态),我想并行执行我的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时,最佳方法应该是什么?
提前致谢 .