2016-10-06 4 views
3

Я создаю Spring 4 Rest API для сайта автоматизации торговли.Весна 4 Задача производительности TaskScheduler

В уровне услуг cronjob динамически создаются с использованием Spring TaskScheduler.schedule(Runnab‌​le arg0, Date arg1) интерфейса, который будет создавать Runnable, которая должна быть выполнена в то время, указанное в качестве параметра, ровно один раз. Этот поток вызовет другую услугу для доступа к моему слою DAB Hibernate и сделает что-то в будущем.

Класс конфигурации и реализация приведены ниже.

@Configuration 
@EnableWebMvc 
@EnableScheduling 
@ComponentScan("com.example")  
public class SpringMvcConfig extends WebMvcConfigurerAdapter {  
    @Bean 
    public ThreadPoolTaskScheduler taskScheduler() { 
     return new ThreadPoolTaskScheduler(); 
    }  
} 


@Service 
public class TransactionServiceImp implements TransactionService { 

    @Autowired 
    private TaskScheduler scheduler; //org.springframework.scheduling.TaskScheduler; 
    @Autowired 
    private TaskExecutorService taskService; //My service 

    @Transactional 
    public myFunction(){ 

     //some code 

     final Long key = //some id value from db 
     Date exeTime = //some java.util.Date in future 

     Runnable runnable = new Runnable() {    

      private long id = key; 
      public void run() { 
       taskService.doSomething(id); 
      } 
     }; 
     ScheduledFuture<?> sheduler = scheduler.schedule(runnable, exeTime); 

     //some code  
    }  
} 

Этот код работает отлично и выполняет задачу в точное время и ровно один раз.

С помощью отладки затмения, его обнаружили, что новый демон поток создается каждый раз, когда scheduler.schedule() называется (при обработке запросов HTTP в Spring MVC). Моя проблема в том,

  1. Является ли мое мышление исправить, что JVM создает новый демон нить на каждом scheduler.schedule() вызова (вместо создания нити в дата-время, указанное)?

  2. Созданные темы демон все еще показывает Running статус в Eclipse, отлаживать даже после того, как задача выполняется. Будет ли нить уничтожена или не закончена run() метод?

  3. Else, будет ли проблема с производительностью?

+0

Это зависит от того, 'TaskScheduler' вы используете. Также вы можете рассмотреть альтернативу. Когда задание запланировано и ваша JVM выйдет из строя, задача исчезнет, ​​если это не проблема, вы, возможно, будете в порядке. Иначе вы можете посмотреть на что-то вроде кварца. –

+0

Я использую интерфейс 'org.springframework.scheduling.TaskScheduler' и реализацию' org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler'. Сбой JVM и ушедшая задача не являются проблемой, поскольку статус транзакции хранится в db, и он будет проверяться при следующем запуске. –

ответ

1

ThreadPoolTaskScheduler обертка ScheduledThreadPoolExecutor (основная реализация JDK), нити могут быть повторно использованы из заранее определенного набора рабочих потоков. Каждая задача назначается/обрабатывается в очередь на работу.

даже основные нити изначально созданы и начали только тогда, когда новые задачи прибывают

Является ли мое мышление исправить, что JVM создает новый демон нитку при каждом вызове scheduler.schedule() (Вместо того, чтобы создавать нить в указано ли дата-время)?

Вы создаете экземпляр потока (Runnable) каждый раз, поскольку он принимает runnable, поэтому ваша задача должна быть выполнена или существующий рабочий поток в очереди, которая может быть бездействующей. если достигнут максимальный размер пула, ваша задача будет ждать.

Созданные потоки демона по-прежнему отображают статус запуска в отладке Eclipse даже после выполнения задачи. Будет ли поток уничтожен или нет при завершении метода run()?

Java док говорит, что это,

выполнение завершится после того, как планировщик выключается или возвращаемый ScheduledFuture будет отменено.

Else, будет ли проблема с производительностью? Максимальное оптимальное количество потоков, которое может быть запущено, ограничено ядрами процессора. Так размер увеличения пула не, обязательно повышает производительность

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html

+0

Спасибо за ваш ответ. При дальнейшей отладке выяснилось, что я неправильно понял потоки Daemon как потоки TaskScheduler. Но это не так. Они создаются для каждого запроса (очевидно, в случае сервлета). Существует только один поток для TaskScheduler, который продолжает работать после первого вызова. Этот единственный поток управляет всеми заданиями, добавленными позже. Поэтому я думаю ** не будет проблем с производительностью для выше кода **, так? –

+0

да это не будет. И FYI, если вы не укажете размер пула, который он предположил 1. – kuhajeyan