当石英作业触发时,它是否是一个新的作业类实例?

我对Quartz很陌生,我对工作生命周期有一些怀疑。

假设我有一个工作配置为做一些事情。

作业触发并结束其工作。当它再次触发时,它是同一个实例(可能由计划程序设置为休眠和唤醒)还是一个新的作业实例(一旦作业结束,它就会被终止,当再次满足触发条件时,将创建新的作业实例)?

我问这样的问题,是因为当我调试我的应用程序(spring 3 mvc与石英支持)时,我看到作业的新实例和每次触发作业时都打开的SimpleThreadPool$WorkerThreadRun()的新线程,以便SimpleThreadPool$WorkerThreadRun()线程堆积起来并且永远不会终止。

我只是想知道这种行为是否正常,或者我一定会填满记忆;-)

任何人都可以给我一些解释吗?提前致谢。


答案 1

Quartz 每次想要触发作业时都会创建作业类的新实例。假设您有数十万个作业计划非常不频繁地触发 - 将所有这些作业保留在内存中会浪费内存。

但是,如果您使用的是对Quartz的Spring支持,特别是MethodInvokingJobDetailFactoryBean,则Spring将处理您作业的生命周期(它基本上调用您的一个Bean的指定方法)。但您的应用程序中似乎并非如此。

当然,在工作完成并且没有其他引用指向它之后(这是正常情况),垃圾回收器最终将释放作业占用的内存)。

最后是关于线程 - Quartz 创建了一个固定的工作线程池(请参阅 org.quartz.threadPool.threadCount 配置选项)。每次运行作业时,Quartz 都可能决定使用不同的线程 - 但它不会为每个触发器创建新线程。


答案 2

我将写关于版本2.1.5(最新版本),但对于其他版本也可能如此。

由“JobFactory”的某些实例创建的具有“newJob”函数的作业实例(例如,SimpleJobFactory)。对“newJob”的调用,在 JobRunShell 类的 “initialize”方法中执行。JobRunShell 对象保存在 “QuartzSchedulerThread.run” 的局部变量中,不存储在任何其他列表或字段中。

因此,为每个触发时间创建的新作业实例,在执行后,垃圾回收器将正常清理它。


推荐