Spring 4 TaskScheduler 性能问题

Ram*_*n R 5 java eclipse spring spring-mvc

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

在服务层,使用 SpringTaskScheduler.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    
    }    
}
Run Code Online (Sandbox Code Playgroud)

这段代码运行良好,并在准确的时间和恰好一次执行任务。

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

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

  2. Running即使在任务执行之后,创建的守护线程仍然在 Eclipse 调试中显示状态。线程是否会在完成run()方法中被破坏?

  3. 否则,这会是一个性能问题吗?

kuh*_*yan 3

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

甚至核心线程也只有在新任务到达时才最初创建和启动

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

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

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

Java 文档是这样说的,

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

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

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