Quartz的线程池解析
【org.quartz.core相关类图】
可以看到核心类为QuartzScheduler
【QuartzScheduler构造函数】
public QuartzScheduler(QuartzSchedulerResources resources, long idleWaitTime, @Deprecated long dbRetryInterval) throws SchedulerException { this.resources = resources; if (resources.getJobStore() instanceof JobListener) { addInternalJobListener((JobListener)resources.getJobStore()); } this.schedThread = new QuartzSchedulerThread(this, resources); ThreadExecutor schedThreadExecutor = resources.getThreadExecutor(); schedThreadExecutor.execute(this.schedThread); if (idleWaitTime > 0) { this.schedThread.setIdleWaitTime(idleWaitTime); } jobMgr = new ExecutingJobsManager(); addInternalJobListener(jobMgr); errLogger = new ErrorLogger(); addInternalSchedulerListener(errLogger); signaler = new SchedulerSignalerImpl(this, this.schedThread); if(shouldRunUpdateCheck()) updateTimer = scheduleUpdateCheck(); else updateTimer = null; getLog().info("Quartz Scheduler v." + getVersion() + " created."); }
这里创建了一个QuartzSchedulerThread并在ThreadExecutor(默认DefaultThreadExecutor )中运行。这里的ThreadExecutor并非我们关心的,继续看QuartzSchedulerThread的run方法。
【QuartzSchedulerThread#run()】
run方法比较长,大意就是根据Trigger找出要运行的job然后在线程池中执行。下面是run方法的代码片段:
JobRunShell shell = null; try { shell = qsRsrcs.getJobRunShellFactory().createJobRunShell(bndle); shell.initialize(qs); } catch (SchedulerException se) { qsRsrcs.getJobStore().triggeredJobComplete(triggers.get(i), bndle.getJobDetail(), CompletedExecutionInstruction.SET_ALL_JOB_TRIGGERS_ERROR); continue; } if (qsRsrcs.getThreadPool().runInThread(shell) == false) { // this case should never happen, as it is indicative of the // scheduler being shutdown or a bug in the thread pool or // a thread pool being used concurrently - which the docs // say not to do... getLog().error("ThreadPool.runInThread() return false!"); qsRsrcs.getJobStore().triggeredJobComplete(triggers.get(i), bndle.getJobDetail(), CompletedExecutionInstruction.SET_ALL_JOB_TRIGGERS_ERROR); }
这里的ThreadPool必须实现org.quartz.spi.ThreadPool接口。
【ThreadPool实现类】
ThreadPool的默认实现类是org.quartz.simpl.SimpleThreadPool。
String tpClass = cfg.getStringProperty(PROP_THREAD_POOL_CLASS, SimpleThreadPool.class.getName());
(from org.quartz.impl.StdSchedulerFactory#instantiate())
这个线程池非常简单,都没有BlockingQueue:
private LinkedList<WorkerThread> availWorkers = new LinkedList<WorkerThread>(); // SimpleThreadPool成员 private LinkedList<WorkerThread> busyWorkers = new LinkedList<WorkerThread>(); // SimpleThreadPool成员
如果与Spring集成,使用org.springframework.scheduling.quartz.SchedulerFactoryBean且配置了taskExecutor(java.util.concurrent.Executor的实现类),则会使用org.springframework.scheduling.quartz.LocalTaskExecutorThreadPool。
if (this.taskExecutor != null) { mergedProps.setProperty(StdSchedulerFactory.PROP_THREAD_POOL_CLASS, LocalTaskExecutorThreadPool.class.getName()); }
(from org.springframework.scheduling.quartz.SchedulerFactoryBean#initSchedulerFactory)
也可以自定义实现类,并为quartzProperties配置org.quartz.threadPool.class参数。