Проблема в том, что ваш код не ориентирован на многопоточность и поэтому потенциально опасен. Также ваш ThreadLocal
не будет работать, поскольку задание будет выполняться в другом потоке, и у него не будет доступа к ThreadLocal
.
- Не восстанавливайте
ThreadLocal
в контроллере. Определите его один раз и оставьте так. - Ваш
JobThread
является синглтоном, который сохраняет состояние (параметры), поэтому останется только последний. - Программирование для интерфейсов
TaskScheduler
вместо конкретных реализаций - Не создавайте поток, поскольку ваш
JobThread
уже Runnable
. - Вместо вашего
JobThread
чтобы быть единственным, создайте новый по мере необходимости и передайте необходимые параметры.
Ваш JobThread
должен выглядеть примерно так.
public class JobThread implements Runnable {
private final Logger log = Logger.getLogger(JobThread.class);
private final JobLauncher jobLauncher;
private final Job job;
private final String tenant;
public JobThread(JobLauncher launcher, Job job, String tenant) {
this.jobLauncher=launcher;
this.job=job;
this.tenant=tenant;
}
@Override
public void run() {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("LaunchTime", System.currentTimeMillis())
.addString("TenantID", tenant);
try {
JobExecution jobExecution = jobLauncher.run(job, jobParameters);
log.info("Job's Status:::" + jobExecution.getStatus());
} catch (JobExecutionException e) {
log.error(e.getMessage(), e);
}
}
}
Тогда в вашем контроллер вводит необходимые JobLauncer
и Job
. При необходимости создайте новый JobThread
и передайте необходимую информацию.
@RestController
@RequestMapping("tenant/batch")
public class BatchController {
@Autowired
private TaskScheduler taskScheduler;
@Autowired
private JobLauncher jobLauncher;
@Autowired
@Lazy
private Job job;
@PostMapping("/schedule")
public void setBatch(@RequestBody BatchBean cron) {
//cron = "*/10 * * * * *";
String tenant = TenantContext.getCurrentTenant();
JobThread task = new JobThread(this.jobLauncher, this.job, tenant);
taskScheduler.schedule(task, new CronTrigger(cron.getCron()));
}
В заключение отметим, что точность System.currentTimeMillis
может отличаться в вашей ОС / системе / архитектуре. См. javado c указанного метода.