quartz定时任务如何防止前一次任务未执行完成,直接跳过本次任务的启动?

pangjingji 2013-05-08 09:28:56
求教:
quartz定时任务如何防止前一次任务未执行完成,取消本次任务的触发,从而防止同一个任务的并发执行?


public class JobOne implements Job {

private static final Logger LOGGER = LoggerFactory
.getLogger(JobOne.class);

/**
* 任务是否正在执行标记 :false--未执行; true--正在执行; 默认未执行
*/
private static boolean isRun = false;

public void execute(JobExecutionContext jobContext)
throws JobExecutionException {
// 任务正在执行,跳过本次执行
if (isRun) {
JobDetail jobDetail = jobContext.getJobDetail();
LOGGER.info(jobDetail.getGroup() + "." + jobDetail.getName()
+ ":前一次未执行完,跳过本次任务!");
return;
}
isRun = true;
task();
isRun = false;
}

/**
* 任务执行的主题
*/
protected void task(){

};

}


小弟原本想在每个任务中都加一个静态变量,标记前一次任务的触发是否执行完成,如果没执行完成跳过本次任务的触发,感觉多此一举,目前没想到好的方法,求教---不胜感激。
...全文
18867 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hgq_work 2013-07-11
  • 打赏
  • 举报
回复
真怀疑你没看过官方的文档。有个statefulejob ,就是你这个用途
pangjingji 2013-05-08
  • 打赏
  • 举报
回复
引用 3 楼 rumlee 的回复:
[quote=引用 2 楼 rumlee 的回复:] quartz能够配置concurrent。
我记得有这个配置的,不过有好久没用过了。如果不能配置,那你就用synchronized手工同步一下就可以了。[/quote] 用synchronized ? 那需要创建一个静态变量,对这个静态变量加锁实现?quartz每次触发一个任务都是会新建一个对象的,只能对静态变量synchronized? 这样做也不太好吧,最坏的情况可能是第一次启动任务执行了很久,接连第二次,第三次启动,都会请求这个锁,这种实现也不好,除非用一个超时锁。
pangjingji 2013-05-08
  • 打赏
  • 举报
回复
引用 2 楼 rumlee 的回复:
quartz能够配置concurrent。
需要引入Spring才可以配置这个参数吧
rumlee 2013-05-08
  • 打赏
  • 举报
回复
引用 2 楼 rumlee 的回复:
quartz能够配置concurrent。
我记得有这个配置的,不过有好久没用过了。如果不能配置,那你就用synchronized手工同步一下就可以了。
rumlee 2013-05-08
  • 打赏
  • 举报
回复
quartz能够配置concurrent。
七神之光 2013-05-08
  • 打赏
  • 举报
回复
用Timer实现吧
pangjingji 2013-05-08
  • 打赏
  • 举报
回复
引用 7 楼 peng_hao1988 的回复:
你的方法也可以,或者用一个线程池,被吊起的任务放到线程池里,如果线程任务又被调起就判断线程池里是否有之前相同的任务,如果有就跳过。没有就启动线程并放到线程池里。
这种方法可行,根据我的理解应该在每个Job中有一个静态的线程池对象,每个任务要继承Runnable或Callable接口,大概需要这么实现:

public class JobTwo implements Job{

	private  static ThreadPoolExecutor pool=(ThreadPoolExecutor)Executors.newCachedThreadPool();
	
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {
		BlockingQueue<Runnable> queue = pool.getQueue();
		if(queue.size()>0){
			System.out.println("前一次任务未执行完成跳过本次任务");
			return;
		}
		pool.submit(new RealJob());
		
	}
	
	
	class RealJob implements Runnable{

		/**
		 * 任务的执行主题
		 */
		@Override
		public void run() {
			
			//ToDo 任务的业务逻辑
			
		}
		
	}

}

有没有方法可以获取Scheduler调度用的线程池看了接口好像也没,谢谢指导。
桃园闲人 2013-05-08
  • 打赏
  • 举报
回复
你的方法也可以,或者用一个线程池,被吊起的任务放到线程池里,如果线程任务又被调起就判断线程池里是否有之前相同的任务,如果有就跳过。没有就启动线程并放到线程池里。

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧