如何中斷正在運行的quartz作業
讓被鎖死的Thread能被強制中斷,可採用template method 設計模式
建立一個抽象類別InterruptableBaseJob並實作InterruptableJob。
InterruptableBaseJob Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public abstract class InterruptableBaseJob implements InterruptableJob {
protected AtomicReference<Thread> reference = new AtomicReference<>(); protected long executedTime = System.currentTimeMillis();
public abstract void run(JobExecutionContext arg) throws JobExecutionException;
public void execute(JobExecutionContext arg) throws JobExecutionException { try { reference.set(Thread.currentThread()); executedTime = System.currentTimeMillis(); run(arg); } finally { reference.set(null); } }
public void interrupt() { // 避免誤觸,讓超過20秒的才能被中斷 if (System.currentTimeMillis() - executedTime < 20 * 1000) { return; }
Thread thread = reference.getAndSet(null); if (thread != null) { thread.interrupt(); LogUtils.system.info("interrupt " + getClass().getName()); } } }
|
create Job have to extends InterruptableBaseJob Example
1 2 3 4 5 6 7 8
| @DisallowConcurrentExecution public class XXXJob extends InterruptableBaseJob {
@Override public void run(final JobExecutionContext ctx) throws JobExecutionException { XXXCache.getInstance().update(); } }
|
CronScheduler Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class CronScheduler {
private static final CronScheduler instance = new CronScheduler(); private Scheduler scheduler;
private CronScheduler() { try { this.scheduler = StdSchedulerFactory.getDefaultScheduler();
this.scheduler.start();
} catch (SchedulerException e) { LogUtils.err.error("CronScheduler Error.", e); } }
public final static CronScheduler getInstance() { return instance; } /** * 強制中斷任務 * 因為刪除定時任務時,quartz還是會等之前的job完成,才會做移除跟新增job的動作,所以job被鎖死時,可考慮強制中斷 * 能被強制中斷的job必須實作InterruptableJob * @param scheduleType * @throws SchedulerException */ // 中斷定時任務 public void interruptScheduleJob(ScheduleType scheduleType) throws SchedulerException { scheduler.interrupt(getJobKey(scheduleType)); } }
|
use CronScheduler interruptScheduleJob method Example
1
| CronScheduler.getInstance().interruptScheduleJob(ScheduleType.XXXJob);
|