2013-02-12 50 views
1

Quartz 2文档清楚地设置SimpleJobDetail以便它执行序列化(即,当前作业在之后运行)通过设置concurrent = false来完成)。 Quartz 2文档对于如何使用InvokeMethodJob设置一个调用spring bean方法的工作也很清楚。但是不清楚的是如何设置InvokeMethodJob来仅运行序列化(并发= false)。我设置InvokeMethodJob像这样的conf/Config.groovy中:如何在Grails 2中使用Quartz 2.x插件设置序列化(非并发)InvokeMethodJob

import static org.quartz.JobBuilder.* 
import static org.quartz.SimpleScheduleBuilder.* 
import static org.quartz.TriggerBuilder.* 
import org.quartz.impl.triggers.* 
import org.quartz.JobDataMap 
import org.quartz.JobDetail 
import org.quartz.Trigger 
import grails.plugin.quartz2.InvokeMethodJob 
//Begin quartz configuration 
grails.plugin.quartz2.autoStartup = true 
    org{ 
     quartz{ 
      scheduler.instanceName = 'MyScheduler' 
    threadPool.class = 'org.quartz.simpl.SimpleThreadPool' 
    threadPool.threadCount = 20 
    threadPool.threadsInheritContextClassLoaderOfInitializingThread = true 
      jobStore.class = 'org.quartz.simpl.RAMJobStore' 
     } 
    } 
grails.plugin.quartz2.jobSetup.mySchedule = { quartzScheduler, ctx -> 
    def props = new JobDataMap([concurrent:false,targetObject:ctx.myActionService,targetMethod:'myaction',arguments:[true]]) 
    JobDetail jobDetail = newJob(InvokeMethodJob.class) 
     .withIdentity("perform my action") 
     .usingJobData(props) 
     .build() 
    Trigger trigger = newTrigger().withIdentity("every 90 seconds trigger") 
     .withSchedule(
      simpleSchedule().withIntervalInSeconds(90).repeatForever() 
     ) 
     .startNow().build() 
    quartzScheduler.scheduleJob(jobDetail, trigger) 
} 

然而,这将允许多个线程同时执行的myActionService.myaction()调用。我希望调度程序在第一次调用返回之前停止对此的进一步调用。

我读到@DisallowConcurrentExecution但没有以应用的方式(或如何应用的例子)中的conf/Config.groovy中内部的一个定义。

我可以设计出最佳的解决方案是创建一个新的Groovy类扩展InvokeMethodJob与@DisallowConcurrentExecution这样的注释:

package com.fourgablesguy.quartz2 

import grails.plugin.quartz2.InvokeMethodJob 
import org.quartz.DisallowConcurrentExecution 

/** 
* InvokeMethodJob that is not concurrently executed, serial execution 
* this has the DisallowConcurrentExecution annotation 
*/ 
@DisallowConcurrentExecution 
class SerializedInvokeMethodJob extends InvokeMethodJob { } 

然后改变的conf/Config.groovy中使用这个新的工作类的类型:

import com.fourgablesguy.quartz2.SerializedInvokeMethodJob 
... 
JobDetail jobDetail = newJob(SerializedInvokeMethodJob.class) 

但我可能错过了一些不太复杂的事情,可以用石英2来完成同样的事情,所以如果有人有不同的解决方案,我就发布了这个。我发现

+1

你已经给出了threadCount = 20意味着没有并行线程正在处理它。也许你可以用1代替它。 – sanghavi7 2013-03-21 10:00:56

回答

2

最佳的解决方案中的问题进行了说明,注释定制InvokeMethodJob类@DisallowConcurrentExecution

的THREADCOUNT = 1可能是一个选项,如果你的系统永远只能做一个任务。如果您有多个不同的作业,则需要更高的线程数,以便它们可以并行运行(您可能希望为非并发的某些作业)。一旦线程数大于1,就不能保证不会发生非并发执行为任何工作。