Должен ли я использовать Spring TaskScheduler для выполнения задачи в указанное время с аннотацией @Async?

Я использую Spring 3 в веб-приложении и хочу запустить задачу через две минуты в будущем (например, отправить электронное письмо). Может быть несколько вызовов для планирования одной и той же задачи разными пользователями (с разными параметрами), поэтому будут некоторые перекрытия очередей планирования.

В другом месте приложения я использую аннотацию Spring @Scheduled для выполнения задачи в стиле cron через равные промежутки времени, поэтому у меня уже есть Выполнение и планирование задач Spring настроены и работают. Поэтому мой файл applicationContext.xml содержит что-то вроде:

<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor  id="myExecutor"  pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/> 

Я написал следующий код в качестве теста, и из вывода, отправленного на консоль, похоже, не имеет значения, использую ли я аннотацию @Async или нет (поведение такое же) .

public static void main(String[] args) {
    ApplicationContext ctx = 
         new ClassPathXmlApplicationContext("applicationContext.xml");
    long start = System.currentTimeMillis();
    long inXseconds = start + (1000 * 10);        
    Date startTime = new Date(start + 5000);
    TaskScheduler taskscheduler = (TaskScheduler) ctx.getBean("myScheduler");

    System.out.println("Pre-calling " + new Date());        
    doSomethingInTheFuture(taskscheduler, startTime, "Hello");
    System.out.println("Post-calling " + new Date());    

    while(System.currentTimeMillis()< inXseconds){            
        // Loop for inXseconds
    }        

    System.exit(0);
}

@Async
private static void doSomethingInTheFuture(
       TaskScheduler taskscheduler, 
       Date startTime, 
       final String attribute){
    // Returns a ScheduledFuture but I don't need it
    taskscheduler.schedule(new Runnable(){
        public void run() {
            System.out.println(attribute);
            System.out.println(new Date());
        }            
    }, startTime);                        
}

Некоторые мой вопрос:

Должен ли я использовать аннотацию @Async и какая разница, если я это сделаю?


person Mark McLaren    schedule 11.05.2012    source источник


Ответы (2)


В вашем случае это не имеет значения, потому что вы аннотировали статический метод аннотацией @Async, и Spring не будет создавать прокси в этом случае.

Если бы вы объявили аннотацию @Async в обычном методе bean-компонента Spring, то поведение заключалось бы в том, чтобы внутренне обернуть его в класс Runnable и отправить его как задачу в пул потоков, и ваш вызываемый метод немедленно вернулся бы — в то время как задача запланировано для выполнения пулом потоков.

person Biju Kunjummen    schedule 11.05.2012
comment
Спасибо Биджу. Так будет ли это похоже на двойное экранирование строки? Например. порождение потока для порождения другого потока - person Mark McLaren; 11.05.2012

Как я понял это единственная разница если поставить аннотацию планировщик будет выполнять эту задачу и переходить к другой. Если выполнение задачи занимает больше вашего интервала (2 минуты) - вы увидите разницу.

Планировщик аннотаций @Asunc запустит новую задачу, не дожидаясь завершения предыдущей. Без этой аннотации он будет ждать завершения текущей задачи.

Таким образом, разница может быть, если выполнение задачи занимает больше вашего интервала (2 минуты).

person alexey28    schedule 11.05.2012