📄 quartzscheduler.java
字号:
}
public void addNoGCObject(Object obj) {
holdToPreventGC.add(obj);
}
public boolean removeNoGCObject(Object obj) {
return holdToPreventGC.remove(obj);
}
/**
* <p>
* Returns the <code>SchedulerContext</code> of the <code>Scheduler</code>.
* </p>
*/
public SchedulerContext getSchedulerContext() throws SchedulerException {
return context;
}
public boolean isSignalOnSchedulingChange() {
return signalOnSchedulingChange;
}
public void setSignalOnSchedulingChange(boolean signalOnSchedulingChange) {
this.signalOnSchedulingChange = signalOnSchedulingChange;
}
///////////////////////////////////////////////////////////////////////////
///
/// Schedululer State Management Methods
///
///////////////////////////////////////////////////////////////////////////
/**
* <p>
* Starts the <code>QuartzScheduler</code>'s threads that fire <code>{@link org.quartz.Trigger}s</code>.
* </p>
*
* <p>
* All <code>{@link org.quartz.Trigger}s</code> that have misfired will
* be passed to the appropriate TriggerListener(s).
* </p>
*/
public void start() throws SchedulerException {
if (closed) {
throw new SchedulerException(
"The Scheduler cannot be restarted after shutdown() has been called.");
}
if (initialStart == null) {
initialStart = new Date();
this.resources.getJobStore().schedulerStarted();
startPlugins();
}
schedThread.togglePause(false);
getLog().info(
"Scheduler " + resources.getUniqueIdentifier() + " started.");
}
/**
* <p>
* Temporarily halts the <code>QuartzScheduler</code>'s firing of <code>{@link org.quartz.Trigger}s</code>.
* </p>
*
* <p>
* The scheduler is not destroyed, and can be re-started at any time.
* </p>
*/
public void standby() {
schedThread.togglePause(true);
getLog().info(
"Scheduler " + resources.getUniqueIdentifier() + " paused.");
}
/**
* <p>
* Reports whether the <code>Scheduler</code> is paused.
* </p>
*/
public boolean isInStandbyMode() {
return schedThread.isPaused();
}
public Date runningSince() {
return initialStart;
}
public int numJobsExecuted() {
return jobMgr.getNumJobsFired();
}
public Class getJobStoreClass() {
return resources.getJobStore().getClass();
}
public boolean supportsPersistence() {
return resources.getJobStore().supportsPersistence();
}
public Class getThreadPoolClass() {
return resources.getThreadPool().getClass();
}
public int getThreadPoolSize() {
return resources.getThreadPool().getPoolSize();
}
/**
* <p>
* Halts the <code>QuartzScheduler</code>'s firing of <code>{@link org.quartz.Trigger}s</code>,
* and cleans up all resources associated with the QuartzScheduler.
* Equivalent to <code>shutdown(false)</code>.
* </p>
*
* <p>
* The scheduler cannot be re-started.
* </p>
*/
public void shutdown() {
shutdown(false);
}
/**
* <p>
* Halts the <code>QuartzScheduler</code>'s firing of <code>{@link org.quartz.Trigger}s</code>,
* and cleans up all resources associated with the QuartzScheduler.
* </p>
*
* <p>
* The scheduler cannot be re-started.
* </p>
*
* @param waitForJobsToComplete
* if <code>true</code> the scheduler will not allow this method
* to return until all currently executing jobs have completed.
*/
public void shutdown(boolean waitForJobsToComplete) {
if(closed == true) {
return;
}
getLog().info(
"Scheduler " + resources.getUniqueIdentifier()
+ " shutting down.");
standby();
closed = true;
schedThread.halt();
resources.getThreadPool().shutdown(waitForJobsToComplete);
if (waitForJobsToComplete) {
while (jobMgr.getNumJobsCurrentlyExecuting() > 0) {
try {
Thread.sleep(100);
} catch (Exception ignore) {
}
}
}
// Scheduler thread may have be waiting for the fire time of an acquired
// trigger and need time to release the trigger once halted, so make sure
// the thread is dead before continuing to shutdown the job store.
try {
schedThread.join();
} catch (InterruptedException ignore) {
}
resources.getJobStore().shutdown();
notifySchedulerListenersShutdown();
shutdownPlugins();
SchedulerRepository.getInstance().remove(resources.getName());
holdToPreventGC.clear();
try {
unBind();
} catch (RemoteException re) {
}
if (resources.getJMXExport()) {
try {
unregisterJMX();
} catch (Exception e) {
}
}
getLog().info(
"Scheduler " + resources.getUniqueIdentifier()
+ " shutdown complete.");
}
/**
* <p>
* Reports whether the <code>Scheduler</code> has been shutdown.
* </p>
*/
public boolean isShutdown() {
return closed;
}
public void validateState() throws SchedulerException {
if (isShutdown()) {
throw new SchedulerException("The Scheduler has been shutdown.");
}
// other conditions to check (?)
}
/**
* <p>
* Return a list of <code>JobExecutionContext</code> objects that
* represent all currently executing Jobs in this Scheduler instance.
* </p>
*
* <p>
* This method is not cluster aware. That is, it will only return Jobs
* currently executing in this Scheduler instance, not across the entire
* cluster.
* </p>
*
* <p>
* Note that the list returned is an 'instantaneous' snap-shot, and that as
* soon as it's returned, the true list of executing jobs may be different.
* </p>
*/
public List getCurrentlyExecutingJobs() {
return jobMgr.getExecutingJobs();
}
///////////////////////////////////////////////////////////////////////////
///
/// Scheduling-related Methods
///
///////////////////////////////////////////////////////////////////////////
/**
* <p>
* Add the <code>{@link org.quartz.Job}</code> identified by the given
* <code>{@link org.quartz.JobDetail}</code> to the Scheduler, and
* associate the given <code>{@link org.quartz.Trigger}</code> with it.
* </p>
*
* <p>
* If the given Trigger does not reference any <code>Job</code>, then it
* will be set to reference the Job passed with it into this method.
* </p>
*
* @throws SchedulerException
* if the Job or Trigger cannot be added to the Scheduler, or
* there is an internal Scheduler error.
*/
public Date scheduleJob(SchedulingContext ctxt, JobDetail jobDetail,
Trigger trigger) throws SchedulerException {
validateState();
if (jobDetail == null) {
throw new SchedulerException("JobDetail cannot be null",
SchedulerException.ERR_CLIENT_ERROR);
}
if (trigger == null) {
throw new SchedulerException("Trigger cannot be null",
SchedulerException.ERR_CLIENT_ERROR);
}
jobDetail.validate();
if (trigger.getJobName() == null) {
trigger.setJobName(jobDetail.getName());
trigger.setJobGroup(jobDetail.getGroup());
} else if (trigger.getJobName() != null
&& !trigger.getJobName().equals(jobDetail.getName())) {
throw new SchedulerException(
"Trigger does not reference given job!",
SchedulerException.ERR_CLIENT_ERROR);
} else if (trigger.getJobGroup() != null
&& !trigger.getJobGroup().equals(jobDetail.getGroup())) {
throw new SchedulerException(
"Trigger does not reference given job!",
SchedulerException.ERR_CLIENT_ERROR);
}
trigger.validate();
Calendar cal = null;
if (trigger.getCalendarName() != null) {
cal = resources.getJobStore().retrieveCalendar(ctxt,
trigger.getCalendarName());
}
Date ft = trigger.computeFirstFireTime(cal);
if (ft == null) {
throw new SchedulerException(
"Based on configured schedule, the given trigger will never fire.",
SchedulerException.ERR_CLIENT_ERROR);
}
resources.getJobStore().storeJobAndTrigger(ctxt, jobDetail, trigger);
notifySchedulerThread();
notifySchedulerListenersSchduled(trigger);
return ft;
}
/**
* <p>
* Schedule the given <code>{@link org.quartz.Trigger}</code> with the
* <code>Job</code> identified by the <code>Trigger</code>'s settings.
* </p>
*
* @throws SchedulerException
* if the indicated Job does not exist, or the Trigger cannot be
* added to the Scheduler, or there is an internal Scheduler
* error.
*/
public Date scheduleJob(SchedulingContext ctxt, Trigger trigger)
throws SchedulerException {
validateState();
if (trigger == null) {
throw new SchedulerException("Trigger cannot be null",
SchedulerException.ERR_CLIENT_ERROR);
}
trigger.validate();
Calendar cal = null;
if (trigger.getCalendarName() != null) {
cal = resources.getJobStore().retrieveCalendar(ctxt,
trigger.getCalendarName());
if(cal == null) {
throw new SchedulerException(
"Calendar not found: " + trigger.getCalendarName(),
SchedulerException.ERR_PERSISTENCE_CALENDAR_DOES_NOT_EXIST);
}
}
Date ft = trigger.computeFirstFireTime(cal);
if (ft == null) {
throw new SchedulerException(
"Based on configured schedule, the given trigger will never fire.",
SchedulerException.ERR_CLIENT_ERROR);
}
resources.getJobStore().storeTrigger(ctxt, trigger, false);
notifySchedulerThread();
notifySchedulerListenersSchduled(trigger);
return ft;
}
/**
* <p>
* Add the given <code>Job</code> to the Scheduler - with no associated
* <code>Trigger</code>. The <code>Job</code> will be 'dormant' until
* it is scheduled with a <code>Trigger</code>, or <code>Scheduler.triggerJob()</code>
* is called for it.
* </p>
*
* <p>
* The <code>Job</code> must by definition be 'durable', if it is not,
* SchedulerException will be thrown.
* </p>
*
* @throws SchedulerException
* if there is an internal Scheduler error, or if the Job is not
* durable, or a Job with the same name already exists, and
* <code>replace</code> is <code>false</code>.
*/
public void addJob(SchedulingContext ctxt, JobDetail jobDetail,
boolean replace) throws SchedulerException {
validateState();
if (!jobDetail.isDurable() && !replace) {
throw new SchedulerException(
"Jobs added with no trigger must be durable.",
SchedulerException.ERR_CLIENT_ERROR);
}
resources.getJobStore().storeJob(ctxt, jobDetail, replace);
}
/**
* <p>
* Delete the identified <code>Job</code> from the Scheduler - and any
* associated <code>Trigger</code>s.
* </p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -