Spring 4 TaskScheduler性能问题

时间:2016-10-06 05:57:45

标签: java eclipse spring spring-mvc

我正在为贸易自动化网站构建Spring 4 Rest API。

在服务层中,使用Spring TaskScheduler.schedule(Runnab‌​le arg0, Date arg1) 接口动态创建cronjob,该接口将创建 Runnable ,在给定的时间执行作为参数,恰好一次。该线程将调用另一个服务来访问我的Hibernate DAO层,并在将来做一些事情。

下面给出了配置类和实现。

@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    
    }    
}

此代码运行正常,可以在确切的时间执行任务

通过eclipse调试,它发现每次调用 scheduler.schedule() 时都会创建一个新的守护程序线程(处理对spring mvc的http请求时)。我的问题是,

  
      
  1. 我的想法是正确的,jvm在每个上都创建了新的守护程序线程   scheduler.schedule()调用(而不是在   指定的日期时间)?

  2.   
  3. 创建的守护程序线程仍在显示 Running 状态       即使在执行任务后Eclipse也会进行调试。请问是这样的       在完成 run() 方法时是否销毁?

  4.   
  5. 否则,这会是性能问题吗?

  6.   

1 个答案:

答案 0 :(得分:2)

ThreadPoolTask​​Scheduler包装ScheduledThreadPoolExecutor(底层的jdk实现),可以从预定义的工作线程集重用线程。每个任务都被分配/处理为工作队列。

  

甚至核心线程最初都是在新的时候创建和启动的   任务到达

我的想法是正确的,jvm在每个scheduler.schedule()调用上创建了新的守护程序线程(而不是在指定的日期时创建线程)?

您每次都在创建线程实例(Runnable),因为它接受runnable,因此您的任务应该被执行,或者队列中的现有工作线程可能处于空闲状态。如果达到最大池大小,您的任务将等待。

即使在执行任务之后,创建的守护程序线程仍在Eclipse调试中显示运行状态。在完成run()方法时线程是否会被销毁?

Java doc说这个,

  

一旦调度程序关闭或返回,执行将结束   ScheduledFuture被取消。

否则,这会是性能问题吗?可以运行的最大最佳线程数受cpu内核的限制。因此,增加池大小不一定会提高性能

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