我正在为贸易自动化网站构建Spring 4 Rest API。
在服务层中,使用Spring TaskScheduler.schedule(Runnable 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请求时)。我的问题是,
我的想法是正确的,jvm在每个上都创建了新的守护程序线程
scheduler.schedule()
调用(而不是在 指定的日期时间)?创建的守护程序线程仍在显示
Running
状态 即使在执行任务后Eclipse也会进行调试。请问是这样的 在完成run()
方法时是否销毁?- 醇>
否则,这会是性能问题吗?
答案 0 :(得分:2)
ThreadPoolTaskScheduler包装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