Я хочу реализовать ExecutorService в моем приложении Spring-MVC.
Мне нужен глобальный ExecutorService, который принимает задачи, помещает их в очередь, а затем выполняет их последовательно. Поэтому я хочу передать задачи из разных мест в приложении. Поэтому я использую Executors.newSingleThreadExecutor();
, поэтому у меня есть только 1 поток, выполняющий эти задачи.
Однако я не уверен, как интегрировать его в приложение Spring:
public enum TaskQueue {
INSTANCE;
ExecutorService executorService;
private TaskQueue() {
executorService = Executors.newSingleThreadExecutor();
}
public void addTaskToQueue (Runnable task){
executorService.submit(task);
executorService.shutdown();
}
}
Итак, я думаю о создании Singleton, а затем просто передать задачу (Runnable объект) методу:
TaskQueue.INSTANCE.addTaskToQueue(new Runnable() {
@Override
public void run() {
System.out.println("Executing Task1 inside : " + Thread.currentThread().getName());
}
});
Однако у меня есть несколько вопросов:
Я не уверен, как интегрировать его в приложение Spring MVC, где у меня есть контроллеры, службы и т. Д.
Приложение получает уведомления от веб-службы. Эти уведомления будут обрабатываться в разных местах кода. я бы хотел
выполнять их последовательно. Поэтому мне нужно определить все задачи, которые я хочу выполнить асинхронно, а затем передать их описанному выше методу (`addTaskToQueue), обернутому в объект Runnabel, чтобы они могли выполняться асинхронно. Это правильный подход?
Поэтому я всегда передаю объекты Runnable этому методу для его выполнения. Этот метод выполняет его и закрывает службу executor. Поэтому каждый раз, когда я передаю задание этому сервису, он создает новый сервис, а затем закрывает его. Но я не хочу иметь это - я хочу, чтобы executorservice оставался в живых и выполнял задачи, которые приходят, а не закрываются после каждой задачи. Как мне этого добиться?
Или я совершенно не прав, реализовав это таким образом?
EDIT:
Используя TaskExecutor, предоставленный Spring - я бы реализовал его так:
@Autowired
private TaskExecutor taskExecutor;
Тогда звоню из другого места в моем коде:
taskExecutor.execute(new Runnable() {
@Override
public void run() {
//TODO add long running task
}
});
Вероятно, мне нужно убедиться, что где-то в конфигурации он должен выполняться последовательно - поэтому он должен создавать только 1 поток. Безопасно ли звонить из разных мест? Не всегда будет создавать новый сервис с новой очередью?