Search code examples
javasingletonscheduler

How avoid blocking singleton service by 2 schedulers beans


having 2 schedulers, both of them using 1 service. I want to use them at the same time, but shedulers block each other. How can i avoid this blocking?

SchedulerA works with queue in main thread, SchedulerB works with queue in ThreadPool, and i need to wait for ending of this work, before run taskB again

Scheduler A:

@Service 
public class SchedulerA {

    private SomeService service;

    @Scheduled(fixedDelay = 2 * 60 * 1000)
    public void taskA() {
        service.methodA();
    }
}

Scheduler B:

@Service
public class SchedulerB {

    private SomeService service;

    @Scheduled(fixedDelay = 2 * 60 * 1000, initialDelay = 1 * 1000)
    public void taskA() {
        List<Future<?>> futures = service.methodB();
        //waiting of ending of all tasks
        for (Future<?> future : futures) {
            try {
                future.get();
            } catch (Exception e) {
                log.error("Error while awaiting tasks termination", e);
            }
        }
    }
}

SomeService for both Schedulers:

@Service
public class SomeService {

    SomeRepository repository;
    ExecutorService executorService = Executors.newFixedThreadPool(10);

    public void methodA() {
        List<Task> tasks = repository.findAllByStatus("readyForTaskA");
        tasks.forEach(task -> runTaskA(task));
    }

    public List<Future<?>> methodB() {
        List<Task> tasks = repository.findAllByStatus("readyForTaskB");
        return tasks.stream()
                .map(task -> executorService.submit(() ->  runTaskB(task)))
                .collect(Collectors.toList());
    }

    private void runTaskA(Task task){
        //do something
    }

    private void runTaskB(Task task) {
        //do something
    }
}

Solution

  • Thats wasnt a singleton blocking problem, all i needed to do was the increasing of taskScheduling pool size, by default size = 1. Resolved by adding parameter spring.task.scheduling.pool.size=2 to application.properties